【问题标题】:Cache PreparedStatement per Connection or let the connection pool handle it?缓存每个连接的 PreparedStatement 还是让连接池处理它?
【发布时间】:2011-06-11 21:12:45
【问题描述】:

哪种缓存策略更快?速度快多少?

1) PreparedStatement 池化(通过连接池)。应用程序没有缓存。

for (int i=0; i<1000; i++) {
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    preparedStatement.setObject(1, someValue);
    preparedStatement.executeQuery();
    preparedStatement.close();
}

2) 应用程序级缓存。没有 PreparedStatement 池。

PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
    preparedStatement.clearParameters();
    preparedStatement.setObject(1, someValue);
    preparedStatement.executeQuery();
}
preparedStatement.close();

这个问题类似于Reusing a PreparedStatement multiple times,除了我期待具体的基准测试结果以及考虑到 PreparedStatement 池。

http://drupal.org/node/550124#comment-2224630 似乎表明应用程序级缓存比 PreparedStatement 池更有效,但差异可以忽略不计。在下定决心之前,我想看看更多的基准。

【问题讨论】:

  • 这种微基准测试很少引出任何有用的数据。现实世界的使用会因使用模式、底层数据库实现、网络、数据库服务器上的内存和其他因素而有很大差异。你为什么不写你的代码,让它工作,并进行测试。然后,如果它被证明太慢,您可以更新实施并确保该软件将继续工作。
  • 我试图了解是否值得将应用程序级缓存引入框架。这将影响整个用户群,因此针对特定用例进行优化不会真正有帮助。我们可以修改一些备受推崇的数据库基准吗?
  • 那么,有没有用户要求这个功能?如果不是,那么也许没有人需要它,您可以为自己节省一些精力,而不是实现一个可能没有多大作用的新功能......只是一个想法!

标签: jdbc prepared-statement connection-pooling


【解决方案1】:

应用程序级别的缓存会更有效,特别是如果您批量执行这些执行。

即使使用连接池,每次连接准备就绪(返回和第四次确认)并关闭所需的网络开销量不仅会使其速度变慢,而且还会增加 SQL 服务器和客户端服务器的 CPU 级别成本.

【讨论】:

  • (据我了解)这不是连接池的工作方式。连接池发生在客户端。当客户端关闭连接时,它实际上保持打开状态,后续客户端可以重用它以及任何经常重新创建的资源(例如PreparedStatements)。
  • 创建连接的过程发生在客户端和服务器上。池化创建多个连接,从而创建到服务器的多个连接。您可以在服务器上监视它时看到它(池连接数)。查询完成后关闭连接,并实时将另一个连接添加到池中。
  • PreparedStatement 与连接池不同。我认为您将批处理与池化混淆了。池化,你需要一个像 HikariCP (github.com/brettwooldridge/HikariCP) 或 BoneCP 这样的第三方库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 1970-01-01
相关资源
最近更新 更多