Hibernate Criteria vs HQL:哪个更快?[关闭]


71

我一直在阅读一些答案,但我仍然感到困惑。为什么?因为您提到的差异与性能无关。它们易于使用。(Objetc(条件)和SQL(hql))。但是由于某些原因,我想知道“条件”是否比hql慢。

我在另一个答案中读到了

“ HQL和criteriaQuery在性能方面有所不同,每次您使用criteriaQuery触发查询时,它都会为表名创建一个新别名,该别名不会反映在任何数据库的上次查询缓存中。这导致了开销编译生成的SQL,需要更多时间来执行。” 由Varun Mehta提供。

这是非常接近但!我在另一个网站(http://gary-rowe.com/agilestack/tag/hibernate/)上阅读过Hibernate 3.3及更高版本不再是这种情况(请阅读:9)Hibernate运行缓慢,因为Criteria接口不一致)

我已经做了一些测试,试图找出差异,但是两者都会生成qry,并且不会更改表的别名。

我很困惑 如果有人知道主要原因,请您能帮助我们。谢谢

Answers:


151

我是2004年编写Hibernate 3查询翻译器的人,所以我对它的工作方式有所了解。

从理论上讲,标准应该比HQL查询具有更少的开销(除了命名查询,我将介绍它)。这是因为Criteria不需要解析任何内容。使用基于ANTLR的解析器解析HQL查询,然后将生成的AST转换为SQL。但是,使用HQL / JPAQL可以定义命名查询,在SessionFactory启动时在其中生成SQL。从理论上讲,命名查询的开销比标准少。

因此,就SQL生成开销而言,我们有:

  1. 名为HQL / JPAQL查询-SQL生成仅发生一次。
  2. 条件-生成前无需解析。
  3. (未命名)HQL / JPAQL查询-解析,然后生成。

也就是说,在我看来,基于解析和SQL生成的开销选择查询技术可能是一个错误。与使用真实数据在真实数据库服务器上执行真实查询相比,此开销通常很小。如果在分析应用程序时确实显示了这些开销,那么也许您应该切换到命名查询。

在确定Criteria和HQL / JPAQL时,我会考虑以下因素:

  • 首先,你必须,如果你决定要确定与具有Hibernate的专有API的依赖在你的代码。JPA没有条件。
  • 条件确实可以很好地处理许多可选的搜索参数,例如您可能会在具有多参数“搜索表单”的典型网页上找到它们。使用HQL,开发人员倾向于使用StringBuilder处理where子句表达式(避免这种情况!)。使用Criteria,您不需要这样做。Hardik发表了类似意见。
  • HQL / JPAQL可以用于大多数其他事情,因为代码往往更小并且更易于开发人员理解。
  • 如果您使用HQL,那么实际上非常频繁的查询可以变成命名查询。经过一些分析后,我希望稍后再进行此操作。

JPA doesn't have Criteria
destan 2014年

3
@destan从JPA 2.x开始。IIRC,JPA 1.x没有。
约书亚·戴维斯

@JoshuaDavis出色的解释。我只想知道为什么我们必须避免使用StringBuilder构造HQL。例如,如何使用可选参数?
bruno.zambiazi 2015年

2
@ bruno.zambiazi如果您要通过字符串连接构建JPAQL / HQL,则很有可能具有动态查询,这就是Criteria查询功能的目的。我倾向于将Criteria用于任何动态内容(例如,查询的变化取决于用户输入)。HTH-乔许
约书亚·戴维斯

1
@ GokulRajK.N。从Criteria或JPQL生成SQL时,显式或隐式联接应该没有太大区别。通常,执行联接所需的时间比生成SQL所需的时间长得多,因此在大多数情况下,在两者之间进行切换不会产生明显的不同。
约书亚·戴维斯

9

我正在处理数百万条唱片。我发现HQL比Criteria快得多。标准在性能上落后很多。

如果您要处理大量数据,请使用HQL。


5
这对我来说没有多大意义。如果您的数据集非常大,则大部分时间都花在等待数据库处理查询上。在这种情况下,从HQL或从Criteria生成SQL所花费的时间并不重要。使用JPAQL命名查询VS“直” JPAQL VS标准的唯一情况是,当你在做相同的查询很多倍。数据集的大小根本不重要。
约书亚·戴维斯

2
可能是您没有正确使用Criteria。还是为数百万条记录中的每条记录创建了一个新的Criteria Query对象?
vinodn 2015年

1
生成的SQL的访问计划可能有所不同。这并不意味着是Criteria的错。
路易斯·马丁内斯

7

我最喜欢动态查询的条件查询。例如,动态添加一些订购或根据某些参数省去某些零件(例如限制)要容易得多。

另一方面,我将HQL用于静态和复杂查询,因为它更易于理解/阅读HQL。另外,我认为HQL功能更强大,例如对于不同的联接类型。

JPA和Hibernate-条件与JPQL或HQL


4
条件可以执行HQL可以执行的大多数联接类型,尽管有时有些尴尬或难以理解(至少在我看来)。绝对正确,HQL更易于阅读!
约书亚·戴维斯

1
顺便说一句,我会投票赞成你的答案...但是你并没有真正回答kcobuntu的问题。
约书亚·戴维斯

26
如果您要复制别人的答案,则至少应提及它。链接到原始答案:stackoverflow.com/a/197496/980103
Soroush Mirzaei 2014年

嗯..我是一个新手,因此我们的用户/主持人并不多。
Hardik Mishra

6

我认为针对HQL的标准的其他优势

编写HQL会使代码混乱。看起来不再像编写干净的面向对象代码了。

在编写Criteria Queries时,IDE会建议我们使用Intellisense,因此犯错误的可能性较小,除非我们在双引号中编写变量名称之类的东西。


5
对于复杂的查询,HQL比条件更易读。
路易斯·马丁内斯

4

你是对的,不是。结果列表与org.hibernate.loader.Loader该类一起从数据库或缓存中检索。如果未启用缓存,则将使用在SessionFactoryImp中创建的Dialect对象构建prepare语句。因此,每个列表调用都会初始化语句。此外,低级查询是自动生成的。基本上,这是一种帮助,但是在某些情况下,手动编写特定查询会更加有效。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.