【发布时间】:2016-11-18 08:41:43
【问题描述】:
我正在使用 Go (1.6.x) sql 包和 PostGres (9.4) 构建 API。我准备好的陈述应该有应用或请求范围吗?阅读文档后,在应用程序级别确定它们的范围以减少准备阶段的数量似乎更有效。但是,也许还有其他考虑因素,准备好的陈述不是为了活那么久?
【问题讨论】:
标签: sql postgresql go prepared-statement postgresql-9.4
我正在使用 Go (1.6.x) sql 包和 PostGres (9.4) 构建 API。我准备好的陈述应该有应用或请求范围吗?阅读文档后,在应用程序级别确定它们的范围以减少准备阶段的数量似乎更有效。但是,也许还有其他考虑因素,准备好的陈述不是为了活那么久?
【问题讨论】:
标签: sql postgresql go prepared-statement postgresql-9.4
准备好的语句是为了让您可以执行重复的 SQL 命令,这些命令可能只是参数值不同。
它们并不意味着“长期”存在,因为准备好的语句可能(如果从事务中调用它们)保留一个活动的数据库连接(“长期”意味着当它们不被使用时;重复执行一个完全没问题的多次准备好声明,即使这需要很长时间)。连接是一种昂贵的资源,只应在需要时保持。只需创建一堆准备好的语句而不关闭它们,您可能会用完活动/允许的连接,然后阻止与数据库服务器的进一步通信。
如果您想在一个 (HTTP) 请求中多次执行具有不同参数的相同 insert、update 或 select 语句,请使用准备好的语句。不要使用准备好的语句来延长 (HTTP) 请求的寿命。
在某些驱动程序实现和数据库服务器中,prepared statements 还可能涉及在 DB 服务器本身上分配的资源(而不是在 Go 应用程序中)。例如,可以在 DB 服务器上预编译准备好的语句,并且服务器可以准备查询执行计划,为其分配某些资源,例如内存。这些可能会被永久保留,直到准备好的语句关闭。
有一篇文章(Myles McDonnell 在下面的 cmets 中发表)详细介绍了 Go 中 Prepared Statements 的实现细节。它提到如果准备好的语句不是从事务中创建的,它们会将连接释放回连接池,但是在需要时,它们会尝试重用它们准备好的相同的语句(因为如果数据库服务器辅助 / 也起着积极的作用在准备好的语句中,它绑定到服务器端的连接)。如果没有,他们将在新连接上
总而言之,您所描述的是一个工作模型,如果您在许多后续请求中需要/执行的准备语句数量较少,则它们可能意味着更短的响应时间。但这也意味着另一方面,从长远来看,它们可能会导致您所有准备好的语句都将在池的所有连接上准备好。确定您的情况是否可以接受。
通常应该避免这种情况(并且准备好的语句在 HTTP 请求结束之前关闭),但是如果您只有其中的几个,并且在许多请求中确实需要它们,您可以将它们移出请求范围。
【讨论】: