我一直在阅读一些较新的JDBC连接池(如Tomcat)不支持客户端语句池。我已经读过这是因为大多数JDBC驱动程序都维护着自己的语句缓存。但是,我没有看到PostgreSQL发生这种情况。
我对此是否正确?如果是这样,我应该使用CAN缓存预准备语句的连接池,以获得最佳的批量插入性能吗?
由于
答案 0 :(得分:0)
Tomcat的JDBC连接池提供StatementCache。我不知道如何使用它(使用JPA),但它承诺在连接上缓存PreparedStatement
和/或CallableStatement
个实例。"
但是对于插入批次,您可能不需要重复使用PreparedStatement
:您可以使用this example中显示的addBatch
方法。但奇怪的是,official documentation表示"此方法无法在PreparedStatement
或CallableStatement
"上调用。我想你必须尝试一下,看看这是否属实,正如Craig Ringer评论的那样:" PgJDBC无论如何只是单独发送它们#34;。
至于性能:在客户端,服务器和驱动程序/网络流量中出现故障。
数据库服务器通常会了解从连接中获得哪些查询(这也是为什么通过连接池重用连接是一个好主意)。我相信一旦同一查询发生超过5次,PostgreSQL数据库服务器将开始记住来自连接的查询。
如果驱动程序正确处理客户端重用的PreparedStatement
,则驱动程序可以决定仅发送新数据而不是整个查询。这对插入语句可以产生显着的正面性能影响(我相信,除其他外,SQL Server的JDBC驱动程序会这样做)。
如果客户端缓存PreparedStatement
(例如语句仅在创建它的连接关闭时关闭),它将有助于不一次又一次地执行相同的代码(也来自驱动程序)。即初始化时间少,垃圾回收少。
作为Tomcat的JDBC连接池的替代示例:我使用了Yapool' s SimpleQueryCache
(example)和MySQL数据库(和JDBC)驱动程序)在一个小的服务器组件中触发了大约15个不同的查询在压力/负载测试期间,我很惊讶池中所需的最大连接数相对较低,这不会影响小服务器组件的速度(即连接是在相对较短的时间内从池中借来的) 。因此,至少在某些情况下,客户端语句缓存可能会产生影响。
在一个侧节点上:如果你使用像Hibernate这样的东西,Hibernate(在水下)会为你完成很多优化,并且很有可能已经为你完成了(语句)缓存。