NHibernate HQL vs CriteriaAPI vs QueryOver vs Linq。性能

时间:2010-07-16 07:07:48

标签: performance nhibernate criteria icriteria

hql与criteriaApi和QueryOver之间的性能差异是什么?是否存在一个比另一个更快或更慢的情况?

编辑:我使用QueryOver和Linq扩展了问题。

=============================================

好吧,我不确定哪个回复标记为答案,所以我会标记最多VoteUp的帖子。我不知道。这实际上是一个问题,而不是一个问题。

4 个答案:

答案 0 :(得分:12)

ICriteria和HQL之间的性能特征差异很小(我不知道QueryOver)的原因很简单。

ICriteria查询默认情况下会尝试实现映射中定义的获取策略,而HQL默认会考虑所有Lazy,并依赖于查询中的连接声明来定义急切获取的内容。

此外,ICriteria依赖于参数传递的映射,而HQL允许显式参数类型,例如IQuery.SetInt32(“fooParam”,5);

真正重要的是ICriteria查询的可插拔性(请参阅ICriteria.CreateCriteria(。。CreateCriteria()等),其中NH引擎必须解析ICriteria并尝试生成最有效的SQL。

另一方面,如果HQL查询产生一致的结果,可能更容易预测它,从而使QueryCache的使用更容易。

无论哪种方式,配置都是使用ISessionFactory创建和映射定义生成一次,而不是内存中的内容,因此性能良好。

实际的SQL生成在两者之间有所不同,这就是ICriteria实用程序的原因 - > HQL不存在。

最后,我的经验告诉我,2之间的表现可能相同或者需要几毫秒。

作为旁注,在映射中尽可能多地声明将导致更简洁的sql生成以及NHibernate操作,例如对于字符串属性映射.hbm.xml中的Length将导致NHibernate在进入数据库之前检查字符串长度。

答案 1 :(得分:6)

就QueryOver而言,我希望性能与Criteria API完全相同,因为它是作为该API的扩展而构建的。因此,对于两个API中的等效查询,我希望生成相同的数据库查询。我在QueryOver和Criteria接口之间注意到的唯一区别是我发现QueryOver接口“更干净”,使用起来更愉快。

根据我的经验,Criteria API比HQL界面获得了更多的“爱”。我遇到了一些情况,我可以使用条件接口来表达某些查询,但我找不到在HQL界面中表达的等效方法。

关于性能,我发现查询被“询问”的方式比选择Criteria API与HQL与QueryOver相比更能影响性能。我会使用为您提供最自然的界面。

答案 2 :(得分:4)

由于语法和类型安全性的提高,QueryOver在很多方面都是Criteria的非常好的替代品。但是,应该注意的是,在QueryOver 中处理lambda表达式会很昂贵(我猜这同样适用于LINQ查询)。因此,虽然执行结束SQL查询不会比其他方法(ICriteria,HQL)更长时间,但将查询对象转换为适当的SQL查询确实需要更长的时间。

作为一个例子,我们一直在开发一个运行数百个QueryOver查询的应用程序(使用ADO.NET批处理支持),我们发现将查询转换为ICriteria几乎使我们执行查询的能力增加了一倍并且CPU使用率降低了一半。我想如果使用二级缓存和查询缓存,处理lambda表达式所涉及的开销可以大大减少;但由于这不适合我们的申请,我自己也没有这样做。

关于哪个更快的问题更普遍的问题:它真的取决于。唯一确定的方法是运行一个分析工具(NHProf为这样的场景创造奇迹)。但一般来说,HQL是最接近SQL的,因此最灵活,允许您更多的范围来优化您的查询。但是,对于绝大多数简单到中间复杂度的查询,ICriteria和HQL之间几乎没有区别。如果动态构建查询,ICriteria查询将更容易使用。

答案 3 :(得分:1)

我还没有找到两者之间的任何区别。话虽如此 - hql具有Criteria-API中没有的功能。

如果你使用前者或后者,这主要是风格和个人偏好的问题。在查询时,从查询到SQL的转换并不是很重要。

来自比我更了解的人:http://ayende.com/Blog/archive/2009/06/01/nhibernate-queries-ndash-should-i-use-hql-or-criteria.aspx