首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该激活c3p0语句池吗?

我应该激活c3p0语句池吗?
EN

Stack Overflow用户
提问于 2010-05-27 11:43:28
回答 2查看 10.6K关注 0票数 18

我们正在运行java6 6/hibernate/C3P0/postgresql堆栈。我们的JDBC驱动程序是8.4-701.jdbc 3

关于准备好的陈述,我有几个问题。我读过关于准备好的陈述的优秀文件

但是,我仍然有一个问题:如何使用postgresql配置c3p0。

现在我们有

代码语言:javascript
复制
 c3p0.maxStatements = 0
 c3p0.maxStatementsPerConnection  =   0

据我理解,准备好的语句和语句池是两件不同的事情:

我们的hibernate堆栈使用准备好的语句。Postgresql正在缓存执行计划。下次使用相同的语句时,postgresql将重用执行计划。这将节省DB中的计划语句的时间。

此外,c3p0可以缓存"java.sql.PreparedStatement“的java实例,这意味着它正在缓存java对象。所以当使用

c3p0.maxStatementsPerConnection = 100 it缓存最多100个不同

对象。它节省了创建对象的时间,但这与postgresql数据库及其准备的语句无关。

对吗?

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

但是c3p0的医生在c3p0已知的缺点里说

语句池的开销太高。对于没有对PreparedStatements执行重要预处理的驱动程序,池开销超过任何节省。因此,默认情况下将关闭语句池。如果您的驱动程序对PreparedStatements进行预处理,特别是通过IPC对关系数据库进行预处理,那么打开语句池可能会大大提高性能。(为此,请将配置属性maxStatements或maxStatementsPerConnection设置为大于零的值。)

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

亲切问候简宁

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-05-27 13:07:21

我不记得Hibernate是否真的存储PreparedStatement实例本身,或者依赖连接提供程序来重用它们。(快速扫描BatcherImpl表明,如果在一行中多次执行相同的PreparedStatement,它将重用最后一个PreparedStatement)

我认为c3p0文档试图指出的一点是,对于许多JDBC驱动程序来说,PreparedStatement是没用的:一些驱动程序最终只需将客户端的参数拼接,然后将构建的SQL语句传递给数据库。对于这些驱动程序来说,PreparedStatements根本不是优势,重用它们的任何努力都是徒劳的。( Postgresql常见问题说,在服务器协议版本3之前,Postgresql就是这种情况,文档中有更详细的信息)。

对于那些有效地处理PreparedStatements的驱动程序来说,仍然有可能需要实际重用PreparedStatement实例以获得任何好处。例如,如果驱动程序实现:

  • Connection.prepareStatement(sql) -创建服务器端语句
  • PreparedStatement.execute(.)等-执行服务器端语句
  • PreparedStatement.close() -释放服务器端语句

这样,如果应用程序总是打开一个准备好的语句,执行它一次,然后再关闭它,那么仍然没有好处;事实上,这可能会更糟,因为现在可能有更多的往返。因此,应用程序需要保存PreparedStatement实例。当然,这会导致另一个问题:如果应用程序占用太多,而每个服务器端语句都消耗了一些资源,那么这可能会导致服务器端问题。在有人直接使用JDBC的情况下,这可能是手动管理的--已知有些语句是可重用的,因此是准备好的;有些语句不是而且只是使用瞬态语句实例。(这是跳过准备语句的其他优点:处理参数转义)

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

这个难题的最后一部分是JDBC驱动程序自己可能决定聪明并执行此操作;服务器本身也可能决定聪明,并检测出提交与前一个类似的语句的客户端。

考虑到Hibernate本身并没有保存PreparedStatement实例的缓存,您需要让c3p0这样做以获得它们的好处。(由于重用缓存计划,应该减少常见语句的开销)。如果c3p0没有缓存准备好的语句,那么驱动程序只会看到应用程序准备语句,执行它,然后再次关闭它。看起来,在应用程序总是这样做的情况下,JDBC驱动程序具有避免准备/执行服务器开销的“阈值”设置。所以,是的,您需要c3p0 do语句缓存。

希望能帮上忙,抱歉太长了。答案是,是,

票数 26
EN

Stack Overflow用户

发布于 2010-06-23 10:12:32

请记住,每个连接都必须缓存语句,这意味着您将不得不消耗相当一部分内存,需要很长时间才能看到任何好处。因此,如果您将其设置为使用100条语句进行缓存,则实际上是100*连接数或其他100/否连接,但仍然需要相当长的时间才能使缓存产生任何有意义的效果。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2920740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档