Hibernate查询与标准性能

时间:2009-11-23 17:20:12

标签: performance hibernate

我最近有一个相当奇怪的现象。必须获得包含具有不同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 <=?)

4 个答案:

答案 0 :(得分:17)

我想我终于找到了原因。似乎每次执行预准备语句时,条件api都会创建新的变量名。每次执行语句时,数据库(在我们的示例中为DB2)都会计算新的查询执行计划。另一方面,HQL使用相同的变量名,允许数据库重用查询执行计划。

答案 1 :(得分:3)

标准,理论上应该比HQL查询具有更少的开销(命名查询除外,我将会得到)。这是因为Criteria不需要解析任何东西。 使用基于ANTLR的解析器解析HQL查询,然后将生成的AST转换为SQL。 但是,使用HQL / JPAQL,您可以定义命名查询,其中在SessionFactory启动时生成SQL。理论上,命名查询的开销小于Criteria。 因此,就SQL生成开销而言,我们有:

  1. 命名为HQL / JPAQL查询 - SQL生成只发生一次。
  2. 标准 - 生成前无需解析。
  3. (非命名)HQL / JPAQL查询 - 解析,然后生成。 也就是说,在我看来,选择基于解析和SQL生成开销的查询技术可能是一个错误。 与使用真实数据在真实数据库服务器上执行实际查询相比,此开销通常非常小。如果在分析应用程序时实际显示此开销,那么您可能应切换到命名查询。
  4. 在Criteria和HQL / JPAQL之间做出决定时,我会考虑以下事项:

    • 首先,您必须决定是否可以依赖 代码中的Hibernate专有API。 JPA没有标准。
    • 标准非常擅长处理许多可选搜索参数 例如,您可能会在具有多参数的典型网页上找到 '搜索表单'。使用HQL,开发人员倾向于使用where子句 StringBuilder的表达式(避免这个!)。有了Criteria,你 不需要这样做。
    • HQL / JPAQL可以用于大多数其他事情,因为代码倾向于 更小,更容易让开发人员理解。
    • 如果您使用,可以将频繁查询转换为命名查询 HQL。经过一些分析后,我宁愿稍后这样做。

    您可以在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语句