![]() |
1
25
我暂时不记得Hibernate是实际存储PreparedStatement实例本身,还是依赖连接提供程序来重用它们。(对batcherimpl的快速扫描表明,如果连续多次执行同一个SQL,则会重用最后一条PreparedStatement) 我认为c3p0文档试图指出的一点是,对于许多JDBC驱动程序来说,PreparedStatement并不有用:有些驱动程序最终只会简单地拼接客户端中的参数,然后将构建的SQL语句传递给数据库。对于这些驱动程序来说,PreparedStatements一点好处也没有,任何重用它们的工作都被浪费了。(The Postgresql JDBC FAQ 说这是在Sever协议版本3之前的PostgreSQL的情况,在 documentation ) 对于确实有效地处理PreparedStatement的驱动程序来说,实际上仍然有必要重用PreparedStatement实例以获得任何好处。例如,如果驱动程序实现:
鉴于此,如果应用程序总是打开一个准备好的语句,执行它一次,然后再次关闭它,那么 仍然 没有好处;事实上,情况可能更糟,因为现在可能会有更多的往返旅行。因此,应用程序需要挂起PreparedStatement实例。当然,这会导致另一个问题:如果应用程序挂起的太多,并且每个服务器端语句都消耗一些资源,那么这会导致服务器端问题。在有人直接使用JDBC的情况下,这可能是手工管理的——一些语句是已知的可重用的,因此是准备好的;一些不是,只是使用临时语句实例。(这跳过了准备好的语句的其他好处:处理参数转义) 所以这就是为什么c3p0和其他连接池也有准备好的语句缓存——它允许应用程序代码避免处理所有这些。这些语句通常保存在一些有限的LRU池中,因此公共语句重用PreparedStatement实例。 最后一个难题是,JDBC驱动程序自己可能会决定是否聪明并做到这一点;服务器自己也可能会决定是否聪明并检测到提交了一个结构类似于前一个语句的客户机。 考虑到Hibernate本身不保存PreparedStatement实例的缓存,您需要让c3p0这样做才能获得它们的好处。(由于重用缓存的计划,应该减少公共语句的开销)。如果c3p0不缓存准备好的语句,那么驱动程序只会看到应用程序正在准备一个语句,执行它,然后再次关闭它。看起来JDBC驱动程序有一个 "threshold" setting 在应用程序总是这样做的情况下,避免准备/执行服务器开销。所以,是的,您需要有c3p0 do语句缓存。 希望能帮上忙,对不起,有点喘不过气来。答案是 对 . |
![]() |
2
2
记住,语句必须根据 连接 这意味着你将不得不消耗相当大的内存,而且要花很长时间才能看到任何好处。因此,如果您将其设置为使用100个要缓存的语句,那么实际上是100*个连接数,或者100/个连接数,但是您仍然需要花费相当长的时间,直到缓存产生任何有意义的效果。 |
|
tggtsed · PostgreSQL从平均值中排除值 1 年前 |
![]() |
Dawid · 为什么我不能在子查询中使用表别名? 2 年前 |
![]() |
CraZyCoDer · 在PostgreSQL中锁定潜在事务 2 年前 |
![]() |
ranebec · 计数时如何返回0而不是null? 2 年前 |
![]() |
Flo · 分组依据中的SQL大小写 2 年前 |