postgresql – 我应该激活c3p0语句池?

前端之家收集整理的这篇文章主要介绍了postgresql – 我应该激活c3p0语句池?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们正在运行java6 / hibernate / c3p0 / postgresql堆栈。
我们的JDBC驱动程序是8.4-701.jdbc3

我有几个关于准备声明的问题。我读过了
优秀文件Prepared Statements

但是我仍然有一个问题如何配置c3p0与postgresql

现在我们有

c3p0.maxStatements = 0
 c3p0.maxStatementsPerConnection  =   0

在我的理解中,准备好的语句和语句池是两个不同的东西:

我们的hibernate栈使用准备好的语句。 Postgresql正在缓存
执行计划。下一次使用相同的语句时,postgresql会重新使用
执行计划。这样可以节省数据库中的时间计划。

另外c3p0可以缓存“java.sql.PreparedStatement”的java实例
这意味着它是缓存java对象。所以使用时
c3p0.maxStatementsPerConnection = 100它最多缓存100个不同的
对象。它可以节省创建对象的时间,但这与之无关
postgresql数据库及其准备语句。

对?

当我们使用大约100个不同的语句我将设置
c3p0.maxStatementsPerConnection = 100

但是c3p0文档在c3p0 known shortcomings中说

The overhead of Statement pooling is
too high. For drivers that do not
perform significant preprocessing of
PreparedStatements,the pooling
overhead outweighs any savings.
Statement pooling is thus turned off
by default. If your driver does
preprocess PreparedStatements,
especially if it does so via IPC with
the RDBMS,you will probably see a
significant performance gain by
turning Statement pooling on. (Do this
by setting the configuration property
maxStatements or
maxStatementsPerConnection to a value
greater than zero.).

那么,用c3p0和Postgresql激活maxStatementsPerConnection是否合理?
激活它有真正的好处吗?

亲切的问候
Janning

如果Hibernate实际上存储PreparedStatement实例,或者依赖于连接提供者重用它,我不记得了。 (BatcherImpl的快速扫描表明,如果连续执行相同的sql多次重复使用最后的PreparedStatement)

我认为c3p0文档试图做的一点是,对于许多JDBC驱动程序,PreparedStatement并不实用:一些驱动程序将最终简单地将客户端中的参数进行拼接,然后将构建的sql语句传递到数据库。对于这些驱动程序,PreparedStatements根本没有任何优势,任何重用它们的努力都是浪费的。 (Postgresql JDBC FAQ说这是Postgresql在服务器协议版本3之前的情况,documentation中有更详细的信息)。

对于有效处理PreparedStatements的驱动程序,实际上可能需要重复使用PreparedStatement实例以获得任何好处。例如,如果驱动程序实现:

> Connection.prepareStatement(sql) – 创建服务器端语句
> PreparedStatement.execute(..)etc – 执行该服务器端语句
> PreparedStatement.close() – 释放服务器端语句

鉴于此,如果应用程序总是打开一个准备好的语句,请执行一次,然后再次关闭,仍然没有任何好处;事实上,由于现在有更多的往返行程,可能会更糟。所以应用程序需要挂起到PreparedStatement实例。当然这会导致另一个问题:如果应用程序挂起太多,并且每个服务器端语句都会消耗一些资源,那么这可能会导致服务器端的问题。在有人直接使用JDBC的情况下,这可能是由手工管理的 – 已知一些语句是可重用的,因此已准备好;有些不是,只是使用transient Statement实例。 (这是跳过准备语句的另一个好处:处理参数转义)

所以这就是为什么c3p0和其他连接池也有准备的语句缓存 – 它允许应用程序代码避免处理所有这一切。这些语句通常保存在一些有限的LRU池中,所以常见的语句重用了PreparedStatement实例。

最终的难题是JDBC驱动程序可能自己决定要聪明,并且服务器本身也可以决定是聪明的,并且检测客户端提交的结构上与之前相似的语句。

鉴于Hibernate本身不保留PreparedStatement实例的缓存,您需要使用c3p0才能获得它们的优势。 (由于重用缓存的计划,应该减少通用语句的开销)。如果c3p0没有缓存准备好的语句,那么驱动程序只会看到应用程序准备一个语句,执行它,然后再次关闭它。看起来JDBC驱动程序有一个“threshold” setting,以避免在应用程序总是这样做的情况下准备/执行服务器开销。所以,是的,你需要有c3p0 do语句缓存。

希望有帮助,对不起,有点长。答案是肯定的。

猜你在找的Postgre SQL相关文章