有一个 SQL PreparedStatement 池是否有意义?

10
作为一个PreparedStatatement包含预编译的SQL命令,因此如果我们创建这种类型的池,就不需要频繁地创建和销毁此对象(就像线程池一样)。
这是否有意义?还是我很困惑?

@user3218114 假设一个应用服务器(当然是极限工作)。 - user2889419
这很大程度上取决于您使用的DBMS(Postgres,Oracle,DB2等)。请添加适当的标签。 - user330315
1
然后驱动程序可以为您完成这个任务(但在服务器端更高效):http://jdbc.postgresql.org/documentation/head/server-prepare.html - user330315
@a_horse_with_no_name 太棒了,谢谢你! - user2889419
简短的回答是否定的。 - user177800
显示剩余5条评论
6个回答

1
我认为你需要的是准备语句的缓存。一些连接池可以作为可选的调优参数来完成这项工作(例如Weblogic,我认为JBoss也可以)。在运行时会多次使用同一个准备语句的情况下非常方便,甚至不一定在同一个事务中。你使用静态变量的方式基本上意味着你只认为会有一个准备语句而不需要缓存多个准备语句,因此从理论上讲它应该可以工作。我不确定的是准备语句缓存是否可以在连接之间共享,或者它是否是特定于连接的。

0

PreparedStatements 被附加到连接上,因此尽管尽可能地重复使用它们是一个好主意,但显式地池化它们不起作用,因为这可能需要您打开太多的连接。另一件要记住的事情是,每个连接只能有一个 ResultSet 打开,因此在不了解应用程序是否需要同时为该语句获取 ResultSet 的情况下,管理哪些语句可以附加到同一连接将会很困难。


没错,这就是为什么你要让池处理所有这些事情。 - eckes

0
不行,因为你每次都必须在客户端上绑定它们。
服务器可能会缓存已编译的 PreparedStatement(例如解析、检查表是否存在和列是否是正确的类型等),这才是你真正想要的。

4
然而,某些连接池和某些JDBC驱动程序会缓存准备好的语句。一些数据库会在服务器端缓存它们。这完全取决于数据库。 - JB Nizet
如果您对它们进行缓存,可以节省客户端和服务器的 CPU 和网络往返。一些 JDBC 库会自行执行此操作,否则您可以让池来完成它。 - eckes

-1

如果您经常执行相同的查询并重复使用连接(通过连接池),那么这是有意义的。在PostgreSQL的pgjdbc-ng JDBC驱动程序中,"driver-side prepared statement cache"可用。缓存的详细信息在pull request 64中有描述。

请注意,这是一种(性能)优化:您不应该依赖它来提高应用程序的速度。应用程序将花费更多的时间等待来自数据库的网络延迟和查询结果,缓存不会改善这一点。调整数据库(模式)和改进网络将产生更大的影响。


-1

如果您在代码的不同位置多次运行相同的查询,则缓存准备语句是有意义的。由于您正在使用PostgreSQL,因此无需从头开始实现它 - PostgreSQL JDBC连接器已经支持此功能(准备好的语句存储在服务器端),请参见此处:http://jdbc.postgresql.org/documentation/head/server-prepare.html

我个人见过它的工作效果,并通过打开此缓存获得了超过200%的提升。


-1

一个指向MySQL手册的链接如何回答关于Postgres的问题? - user330315
1
这适用于大多数数据库。 - Sandeep Vaid
不,它不一样。Postgres的工作方式与MySQL完全不同。 - user330315
1
我曾经在Oracle和MySQL上工作过,这对它们来说都很适用。但是无论如何,问题并没有提到Postgres。 - Sandeep Vaid
它被标记为 postgresql - user330315

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接