Java Hibernate参数化sql查询慢速和活动oracle会话
几天来,我一直在为针对Oracle数据库的hibernate查询而苦苦挣扎。 类似这样的东西,用于将记录提供给网格Java Hibernate参数化sql查询慢速和活动oracle会话,java,spring,oracle,performance,hibernate,Java,Spring,Oracle,Performance,Hibernate,几天来,我一直在为针对Oracle数据库的hibernate查询而苦苦挣扎。 类似这样的东西,用于将记录提供给网格 SELECT fields FROM tables and JoinedTables WHERE Field1 >= :value1 AND Field2 = :value2 AND Field3 = :value3 Order By MaintTable.Id Desc 在SpringJava+Hibernate4.2
SELECT
fields
FROM
tables and JoinedTables
WHERE
Field1 >= :value1
AND Field2 = :value2
AND Field3 = :value3
Order By MaintTable.Id Desc
在SpringJava+Hibernate4.2方法中使用这种方法
SQLQuery query = (SQLQuery) session.createSQLQuery(querySql)
.addEntity(CertificateViewEnt.class)
.setParameter("value1", firstCertificateRecordDate)
.setParameter("value2", certType.toUpperCase())
.setParameter("value3", deleted? 1:0);
每个筛选字段都已正确索引,并在Maintable.Id子代上创建了一个函数索引,以提高性能
起初我以为是会话/连接池没有得到正确管理,所以我改为无状态会话,并添加了此会话。close()
因为在日志中看到它们作为绑定参数传递给Oracle
...
Order By Certificado.Id Desc ) row_
where rownum <= ?)
where rownum_ > ?
这是:
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [2] as [VARCHAR] - E
2015-09-15 14:09:53 DEBUG Loader:2031 - bindNamedParameters() 0 -> deleted [3]
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [3] as [INTEGER] - 0
2015-09-15 14:09:53 TRACE Loader:1931 - Bound [7] parameters total
/*
SLOW here !!! Around 3 secs when query runs in ~0,300 secs via SQL client.
And ACTIVE sessions are left running in Oracle.
*/
2015-09-15 14:09:56 TRACE JdbcCoordinatorImpl:397 - Registering result set [org.apache.commons.dbcp.DelegatingResultSet@f0c620]
2015-09-15 14:09:56 TRACE Loader:943 - Processing result set
最后,我不得不放弃所有Hibernate绑定参数,实现自定义计算分页,并编写所有SQL来检索页面行,它正确地运行和管理db会话
所以,我的问题是:
hibernate在阻止查询在针对数据库运行时运行的场景后面做了什么?
绑定参数查询是否存在任何已知问题
当我有绑定参数时,我真的不喜欢编写所有的SQL代码并强制硬解析这个SQL
关于环境的一些注意事项:
Tomcat和Oracle在同一台主机上。因此,网络连接不是问题所在
Hibernate版本4.2.15最终版
该表在dev数据库中有大约300k条记录(生产时为1.5M),并显示一次10、20、50条记录的页面,按主键Desc排序(生成的序列)
希望一些Hibernate专家能在这方面帮助我,这样我仍然可以信任大型数据库项目上的Hibernate查询。
提前感谢。我不知道这是否是您的问题,但Oracle在解析查询时会查看绑定变量值,然后保存查询计划以备将来执行,因此它不必在每次使用新的绑定变量集运行查询时都继续解析查询。但是每隔一段时间查询就会被重新解析。如果在解析过程中碰巧传递了一些异常的bind变量值,那么将存储并使用一个错误的计划。这是绑定变量的诅咒。它们减少了解析,但在再次解析查询时,可以根据非典型绑定变量值改变计划。提示会有所帮助。我们使用SQL概要文件来锁定带有绑定变量的查询计划,这些变量倾向于更改计划。有时,您可以自定义收集优化器统计信息的时间和方式,以便创建好的计划,而不管将什么值传递到绑定变量中 无论如何,这是我一直看到的事情,可能是你的问题,也可能不是
鲍比也有同样的问题。在MySQL Workbench中,查询需要0毫秒。在Hibernate中,查询需要1500毫秒。取出所有Hibernate参数,并使用SQL字符串中设置的所有参数自行构建SQL查询。这对我有用。就像是JDBC的老派查询一样。谢谢你的提示。绝对值得一试@吉尔伯托普·科托:你找到解决办法了吗?嗨,维沙,我刚才在你之前的评论中提到过。所以,我并没有通过Hibernate查询解决它。相反,我只是使用Hibernate来序列化结果。这很有意义。谢谢
...
Order By Certificado.Id Desc ) row_
where rownum <= ?)
where rownum_ > ?
2015-09-15 14:09:53 TRACE QueryPlanCache:200 - Located native-sql query plan in cache (SELECT /*+ INDEX(
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [2] as [VARCHAR] - E
2015-09-15 14:09:53 DEBUG Loader:2031 - bindNamedParameters() 0 -> deleted [3]
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [3] as [INTEGER] - 0
2015-09-15 14:09:53 TRACE Loader:1931 - Bound [7] parameters total
/*
SLOW here !!! Around 3 secs when query runs in ~0,300 secs via SQL client.
And ACTIVE sessions are left running in Oracle.
*/
2015-09-15 14:09:56 TRACE JdbcCoordinatorImpl:397 - Registering result set [org.apache.commons.dbcp.DelegatingResultSet@f0c620]
2015-09-15 14:09:56 TRACE Loader:943 - Processing result set