据我的理解,您可以在Postgresql中使用预先准备好的语句或连接池(使用pgPool/pgBouncer等工具),但可以同时使用一个语句或连接池(至少使用.NET的Npgsql驱动程序,加上库作者建议在使用PgBouncer时关闭客户端连接池。)。我说的对吗?
如果是这样的话--对于其他运行时和语言,比如Java、Python、Go,这是正确的吗?或者这是一个具体的实现问题?
发布于 2018-05-08 21:35:54
这是一个复杂的问题,但这里有一些答案。
正如@laurenz-albe所写,您可以使用pgb保镖和准备好的语句,但需要使用会话池。这允许您在连接期间使用准备好的语句(即,只要您的NpgsqlConnection实例是打开的)。但是,如果您处于一个短暂的连接场景中(例如,web应用程序为每个HTTP请求打开和关闭一个连接),那么您就倒霉了。从这个意义上说,可以说池和准备好的语句是不兼容的。
但是,如果您使用的是Npgsql的内部池机制(默认情况下),而不是使用pgb强,那么您准备好的语句就会在打开/关闭连接时自动持久化。换句话说,当您调用NpgsqlCommand.Prepare()时,如果物理连接碰巧已经准备好了SQL,则重复使用准备好的语句。这是专门用来为短命连接场景解锁准备语句的速度优势的。这是Npgsql,有关更多信息,请参阅文档。的一个非常独特的行为。
这是进程内连接池的优点之一,而不是进程外池(如pgbouncer )在传递时保留有关物理连接的信息,在这种情况下,需要准备语句的表(name和SQL)。
发布于 2018-05-08 10:35:32
我认为这是一个一般性的问题,所以我会给出一个一般性的答案。适用于特定连接池实现的方面可能会有所不同。
有几种连接池模式:
这取决于您使用哪种连接池。基本上,线程保持连接的时间越长,使用准备好的语句就越有意义。
当然,如果您知道自己在做什么,您也可以在数据库连接建立之后立即创建一个准备好的语句,并且永远不会释放它。只有当所有线程都需要相同的准备语句时,这才能工作。这样的设置很容易搞砸。
https://stackoverflow.com/questions/50231346
复制相似问题