在一个特定的项目中,我遇到了一个在不同配置下使用类型查询的问题。
当在TypedQuery上设置maxResults值大于查询返回的实际结果数时,getResultList()执行起来需要很长时间(有时需要花费长达350秒才能检索到由6列组成的10行)。
相比之下,没有setMaxResults的同一查询需要大约15秒才能执行。如果将WHERE参数更改以检索更多的结果,则同一查询也非常快。
我正在使用资源本地数据源在Junit测试类中进行所有这些测试,但是在Weblogic 10.3.6上使用JTA数据源也会出现相同的情况(以及Jboss EAP 6.1,但我认为这并不重要)。
我尝试在persistence.xml中调整hibernate.jdbc.fetch_size和hibernate.jdbc.wrap_result_sets,但很难估计是否会有改进:一旦查询成功并被Oracle缓存,无论我如何调整这些值,它都将快速执行(我没有清除Oracle语句缓存的权限)。
我注意到,如果从查询中删除ORDER BY,则执行时间会降至50-60秒,这仍然太长,但仍小于350秒。但是该列已经被索引了(它是主键),因此我不理解为什么会对性能产生如此大的影响。
我使用Criteria API构建我的查询,但我也尝试过HQL或本地SQL。我使用CriteriaQuery#multiSelect仅检索所需字段,然后将结果分配给带有适当构造函数的类(select new ...)。
以下是Hibernate翻译的查询:
在SQLDeveloper中运行此代码时,速度很快(应该如此),通常少于一秒钟。但是,在调试Hibernate代码时,我发现
配置:
- Java 6 - Hibernate 3.6.10(JPA 2.0)(尝试升级到Hibernate 4和JPA 2.1,没有变化) - Oracle数据库11g(11.1.0.7.0) - Oracle jdbc驱动程序11.2.0.3(尝试使用11.1.0.7.0和11.2.0.4,没有变化)。 - hibernate.dialect:Oracle10gDialect。
可能重复:ResultSet.next very slow only when query contains FIRST_ROWS or ROWNUM restriction
当在TypedQuery上设置maxResults值大于查询返回的实际结果数时,getResultList()执行起来需要很长时间(有时需要花费长达350秒才能检索到由6列组成的10行)。
相比之下,没有setMaxResults的同一查询需要大约15秒才能执行。如果将WHERE参数更改以检索更多的结果,则同一查询也非常快。
我正在使用资源本地数据源在Junit测试类中进行所有这些测试,但是在Weblogic 10.3.6上使用JTA数据源也会出现相同的情况(以及Jboss EAP 6.1,但我认为这并不重要)。
我尝试在persistence.xml中调整hibernate.jdbc.fetch_size和hibernate.jdbc.wrap_result_sets,但很难估计是否会有改进:一旦查询成功并被Oracle缓存,无论我如何调整这些值,它都将快速执行(我没有清除Oracle语句缓存的权限)。
我注意到,如果从查询中删除ORDER BY,则执行时间会降至50-60秒,这仍然太长,但仍小于350秒。但是该列已经被索引了(它是主键),因此我不理解为什么会对性能产生如此大的影响。
我使用Criteria API构建我的查询,但我也尝试过HQL或本地SQL。我使用CriteriaQuery#multiSelect仅检索所需字段,然后将结果分配给带有适当构造函数的类(select new ...)。
以下是Hibernate翻译的查询:
SELECT * FROM
(SELECT message0_.MESG_ID AS col_0_0_,
message0_.CREATION_DATE AS col_1_0_,
messagetyp1_.MSGT_ID AS col_2_0_,
message0_.MESSAGE_NAME AS col_3_0_,
interview2_.INVW_ID AS col_4_0_,
interview2_.IVWT_ID AS col_5_0_,
party3_.LICENSE_USERNAME AS col_6_0_
FROM message0_
LEFT OUTER JOIN S399_MESSAGE_TYPES messagetyp1_
ON message0_.MSGT_ID=messagetyp1_.MSGT_ID
LEFT OUTER JOIN S399_INTERVIEWS interview2_
ON message0_.INVW_ID=interview2_.INVW_ID
LEFT OUTER JOIN S399_PARTIES party3_
ON message0_.PRTY_ID =party3_.PRTY_ID
WHERE message0_.CREATION_DATE>=?
AND (interview2_.IS_POLLING IS NULL
OR interview2_.IS_POLLING =0)
ORDER BY message0_.MESG_ID DESC
)
WHERE rownum <= ?
在SQLDeveloper中运行此代码时,速度很快(应该如此),通常少于一秒钟。但是,在调试Hibernate代码时,我发现
ps.executeQuery()
上的org.hibernate.jdbc.AbstractBatcher.getResultSet(PreparedStatement)
异常缓慢。这是否应该指向JDBC驱动程序问题或数据库问题?感谢您提前对此情况的任何建议或想法。配置:
- Java 6 - Hibernate 3.6.10(JPA 2.0)(尝试升级到Hibernate 4和JPA 2.1,没有变化) - Oracle数据库11g(11.1.0.7.0) - Oracle jdbc驱动程序11.2.0.3(尝试使用11.1.0.7.0和11.2.0.4,没有变化)。 - hibernate.dialect:Oracle10gDialect。
可能重复:ResultSet.next very slow only when query contains FIRST_ROWS or ROWNUM restriction
select * from (...) where rownum <= ?
)。请参阅经常引用的文章:http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html - Virginieorder by
放在内部查询中。我想知道,因为你最初的问题没有显示它。 - HAL 9000