Postgresql - 准备好的语句与连接池 - 这是一个权衡吗?

che*_*r89 1 postgresql connection-pooling prepared-statement npgsql pgbouncer

据我了解,您可以在 Postgresql 中使用准备好的语句或连接池(使用 pgPool/pgBouncer 等工具),但同时只能从其中之一中受益(至少使用 .NET 的 Npgsql 驱动程序,加上库作者建议关闭客户端)使用 PgBouncer 时的侧连接池)。我对吗?
如果是这样 - 对于其他运行时和语言(例如 Java、Python、Go)也是如此吗?或者这是一个特定于实施的问题?

Sha*_*sky 5

这是一个复杂的问题,但这里有一些答案。

正如 @laurenz-albe 所写,您可以使用 pgbouncer 和准备好的语句,但需要使用会话池。这允许您在连接期间使用准备好的语句(即只要您的 NpgsqlConnection 实例打开)。但是,如果您处于短暂的连接场景(例如,为每个 HTTP 请求打开和关闭连接的 Web 应用程序),那么您就不走运了。从这个意义上说,我们可以说池化和准备好的语句不兼容。

但是,如果您使用 Npgsql 的内部池机制(默认情况下打开)而不是 pgbouncer,那么您准备好的语句将在连接打开/关闭时自动保留。换句话说,当您调用 时NpgsqlCommand.Prepare(),如果物理连接恰好已经准备好 SQL,则将重用准备好的语句。这样做是专门为了释放准备好的语句对于短期连接场景的速度优势。这是 Npgsql 的一个非常独特的行为,请参阅文档以获取更多信息

这是进程内连接池的优点之一,与进程外池(例如 pgbouncer)相反 - Npgsql 在传递时保留有关物理连接的信息,在本例中是一个包含语句的表准备好(名称和 SQL)。