我使用Go(1.6.x)sql包和PostGres(9.4)构建API。我准备好的陈述是否有申请或要求范围?阅读完文档后,将它们放在应用程序级别以减少准备阶段的数量似乎更有效。但是,也许有其他考虑因素和准备好的陈述不是为了长寿而设计的?
答案 0 :(得分:1)
准备好的语句使您可以执行重复的SQL命令,这些命令可能仅在参数值方面有所不同。
它们并不意味着“长”,因为准备好的语句可能(如果从事务中调用它们)保留活动数据库连接(“长”意味着它们不被使用时;重复执行一个完全正常准备好的声明很多次,即使这将需要很长时间)。连接是一种昂贵的资源,只要需要就可以保留。只需创建一堆预准备语句而不关闭它们,就可能会耗尽活动/允许的连接,然后阻止与数据库服务器的进一步通信。
如果要在一个(HTTP)请求中多次执行具有不同参数的相同insert
,update
或select
语句,请使用预准备语句。不要使用预准备语句来超过(HTTP)请求。
在某些驱动程序实现和数据库服务器中,预处理语句也可能涉及在DB服务器本身上分配的资源(不在Go应用程序中)。例如,可以在DB服务器上预编译准备好的语句,并且服务器可以准备查询执行计划,为其分配诸如存储器的某些资源。在准备好的陈述结束之前,这些可以永久保留。
有一篇文章(由Myles McDonnell在下面的评论中发布)进入Go中Prepared Statements的实现细节。它提到如果预处理语句不是从事务创建的,它们会将连接释放回连接池,但是在需要时,它们会尝试重用它们所准备的语句(因为如果数据库服务器帮助/也起着活动作用)在准备好的语句中,它绑定到服务器端的连接)。如果没有,他们将在新连接上重新准备(导致不良的性能开销)。
总而言之,您所描述的是一种工作模型,如果您在许多后续请求中需要/执行的准备语句数量较少,则可能意味着更短的响应时间。但另一方面,这也意味着从长远来看,它们可能会导致所有准备好的语句都在池的所有连接上准备好。在你的情况下决定这是否可以接受。
通常应该避免这种情况(并且在HTTP请求结束之前关闭准备好的语句),但是如果你只有少数几个并且在许多请求中确实需要它们,那么你可以将它们移出请求范围。