我最近有一个相当奇怪的现象。必须获得包含具有不同WHERE条件的多个表的连接的计数。我首先使用hibernate的标准API实现了查询。它正确地创建了所请求的准备好的SQL语句,但速度相当慢。使用HQL重新实现整个查询。这样做是相当讨厌的,但结果的执行速度比使用Criteria API快得多。有人知道这种行为的原因吗?我假设Criteria和HQL框架使用相同的代码库将其转换为SQL。
以下是查询:
select count(*) from R r where r.ISREPLACEDBY = 0
and r.STATUS='OK' and r.A = ?
and r.C in
(select distinct RC from CX cx where cx.FROMDATE >= ? and cx.FROMDATE <=?)
答案 0 :(得分:17)
我想我终于找到了原因。似乎每次执行预准备语句时,条件api都会创建新的变量名。每次执行语句时,数据库(在我们的示例中为DB2)都会计算新的查询执行计划。另一方面,HQL使用相同的变量名,允许数据库重用查询执行计划。
答案 1 :(得分:3)
标准,理论上应该比HQL查询具有更少的开销(命名查询除外,我将会得到)。这是因为Criteria不需要解析任何东西。 使用基于ANTLR的解析器解析HQL查询,然后将生成的AST转换为SQL。 但是,使用HQL / JPAQL,您可以定义命名查询,其中在SessionFactory启动时生成SQL。理论上,命名查询的开销小于Criteria。 因此,就SQL生成开销而言,我们有:
在Criteria和HQL / JPAQL之间做出决定时,我会考虑以下事项:
您可以在http://tech.puredanger.com/2009/07/10/hibernate-query-cache/
阅读其他一些信息答案 2 :(得分:0)
我一般认为HQL非常接近最优,因为它几乎是直接的SQL,有一些替换。我假设从HQL到SQL的转换只是替换; Criteria API可能会生成HQL然后进行转换。通常HQL是你最好的选择。
答案 3 :(得分:0)
Hibernate Criteria使用反射生成SQL语句