【发布时间】:2023-04-08 11:26:01
【问题描述】:
在一个特定的项目中,我遇到了不同配置下的类型化查询问题。
当在 TypedQuery 上设置的 maxResults 值大于查询返回的实际结果数时,getResultList() 需要很长时间才能执行(有时最多需要 350 秒才能检索由 6 列组成的 10 行)。
相比之下,没有 setMaxResults 的相同查询需要大约 15 秒才能执行。更改WHERE 参数以检索更多结果的相同查询也非常快。
我正在使用本地资源数据源的 Junit 测试类中测试所有这些,但是 Weblogic 10.3.6(以及 Jboss EAP 6.1)上的 JTA 数据源也会发生同样的情况,但我认为不是相关)。
我尝试在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
【问题讨论】:
标签: java sql oracle hibernate jpa