Gil*_*rto 9 java oracle performance spring hibernate
通过对Oracle数据库进行hibernate查询,我一直在苦苦挣扎几天.这样的东西用于将记录提供给网格.
SELECT
fields
FROM
tables and JoinedTables
WHERE
Field1 >= :value1
AND Field2 = :value2
AND Field3 = :value3
Order By MaintTable.Id Desc
Run Code Online (Sandbox Code Playgroud)
在Spring Java + Hibernate 4.2方法中使用这种方法.
SQLQuery query = (SQLQuery) session.createSQLQuery(querySql)
.addEntity(CertificateViewEnt.class)
.setParameter("value1", firstCertificateRecordDate)
.setParameter("value2", certType.toUpperCase())
.setParameter("value3", deleted? 1:0);
Run Code Online (Sandbox Code Playgroud)
每个过滤的字段都被正确编入索引并在Maintable.Id Descendent上创建一个函数索引以提高性能.
起初我以为是会话/连接池没有被正确管理,所以我改为StatelessSession并添加了这个session.close():
query.setCacheable(false)
.setTimeout(30)
.setReadOnly(true);
...
...
//Pagination
query.setMaxResults(rows);
query.setFirstResult(HelperMethod(page, rows));
result = (List<CertificateViewEnt>) query.list();
session.close();
return result;
Run Code Online (Sandbox Code Playgroud)
它没有解决它.查询运行好几次,但由于某些未知原因,并且使用之前已成功运行的值,挂起,在Oracle中打开会话(status = ACTIVE)并在超时时失败.在任何SQL客户端上针对Oracle运行相同的查询,并且使用所有可能的params组合进行数十次执行,具有极高的性能,大约400ms,一次10个记录.
在这里和那里阅读了一些文章之后,Link1 [ Hibernate + Java的性能降低但是当我使用TOAD时使用相同的本机Oracle查询 Link2:[ 查询挂起oracle 10g]
我怀疑Hibernate使用的QueryPlan很差,并决定使用绑定参数删除所有过滤器并且也没有解决,尽管它有点好一些.在转移到其他页面(如第1页,第2,3,4页,......)后一段时间被绞死
毕竟,我怀疑Hibernate的方法生成的SQL
query.setMaxResults(rows)
query.setFirstResult(SomeHelperMethod(page, rows));
Run Code Online (Sandbox Code Playgroud)
因为在日志中看到它们作为绑定参数传递给Oracle.
...
Order By Certificado.Id Desc ) row_
where rownum <= ?)
where rownum_ > ?
Run Code Online (Sandbox Code Playgroud)
我也在跟踪日志中看到了这一点
2015-09-15 14:09:53 TRACE QueryPlanCache:200 - Located native-sql query plan in cache (SELECT /*+ INDEX(
Run Code Online (Sandbox Code Playgroud)
还有这个:
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
Run Code Online (Sandbox Code Playgroud)
最后,我不得不放弃所有Hibernate绑定参数并实现自定义计算分页并编写所有SQL来检索页面行,并正确运行和管理数据库会话.
所以,我的问题是: 什么是hibernate正在破坏阻止查询在数据库运行时运行的场景?绑定参数查询有任何已知问题吗?
当我有绑定参数时,我真的不喜欢编写所有SQL代码并强制对此SQL进行硬解析.
关于环境的一些注意事项:Tomcat和Oracle位于同一主机上.所以网络连接不是问题
Hibernate版本4.2.15最终版
该表在开发数据库中有大约300k recs(生产中为1,5M),并且一次显示10,20,50个rec的页面,按主键描述排序(生成序列)
希望一些Hibernate专家可以帮助我,这样我仍然可以信任大型数据库项目上的Hibernate查询.提前致谢.
小智 2
我不知道这是否是您的问题,但是 Oracle 在解析查询时会查看绑定变量值,然后保存查询计划以供将来执行,因此每次使用新的查询运行时都不必继续解析查询绑定变量集。但每隔一段时间就会重新解析查询。如果在解析期间碰巧传递了一些不寻常的绑定变量值,则会存储和使用错误的计划。这是绑定变量的诅咒。它们减少了解析,但在再次解析查询时可以翻转非典型绑定变量值的计划。提示可以提供帮助。我们使用 SQL 配置文件来锁定具有倾向于更改计划的绑定变量的查询计划。有时,您可以自定义收集优化器统计信息的时间和方式,以便无论传递给绑定变量的值是什么,都可以创建良好的计划。
不管怎样,这是我一直看到的东西,可能是也可能不是你的问题。
鲍比
| 归档时间: |
|
| 查看次数: |
2736 次 |
| 最近记录: |