首页 文章

Hibernate Criteria vs HQL:哪个更快?

提问于
浏览
59

我一直在读一些水壶,但我仍然感到困惑 . 为什么?因为你提到的差异与绩效无关 . 它们与易用性有关 . (Objetc(标准)和SQL(hql)) . 但我想知道“条件”是否因某种原因比hql慢 .

我在另一个回答中读到了这个

“HQL和criteriaQuery之间的性能存在差异,每次使用criteriaQuery触发查询时,它都会为表名创建一个新别名,这不会反映在任何数据库的最后一个查询缓存中 . 这会导致开销编译生成的SQL,花费更多时间来执行 . “作者:Varun Mehta .

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

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

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

5 回答

  • 3

    我是2004年编写Hibernate 3查询翻译器的人,所以我知道它是如何工作的 .

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

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

    • 命名的HQL / JPAQL查询 - SQL生成只发生一次 .

    • Criteria - 生成之前无需解析 .

    • (非命名)HQL / JPAQL查询 - 解析,然后生成 .

    那就是说, choosing a query technique based on the overhead of parsing and SQL generation is probably a mistake 在我看来 . 与使用真实数据在真实数据库服务器上执行实际查询相比,此开销通常非常小 . 如果在分析应用程序时实际显示此开销,那么您可能应该切换到命名查询 .

    在Criteria和HQL / JPAQL之间做出决定时,我会考虑以下事项:

    • 首先,你必须决定你的代码中是否有 dependency on Hibernate-proprietary API . JPA没有Criteria .

    • Criteria is really good at handling many optional search parameters ,例如您可能在具有多参数'search form'的典型网页上找到 . 使用HQL,开发人员倾向于使用StringBuilder( avoid this! )来处理where子句表达式 . 使用Criteria,您不需要这样做 . Hardik发表了类似的意见 .

    • HQL / JPAQL可用于大多数其他事情,因为代码往往更小,更容易让开发人员理解 .

    • 如果使用HQL,可以将频繁查询转换为命名查询 . 经过一些剖析后,我宁愿稍后再这样做 .

  • 1

    我正在研究数百万的记录 . 我发现HQL比Criteria快得多 . 标准在性能方面落后很多 .

    如果您正在处理大量数据,那么请转到HQL .

  • 7

    Other Advantages I think for Criteria over HQL

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

    在编写Criteria Queries时,IDE建议我们使用Intellisense,因此除了在双引号中编写类似变量名的内容之外,提交错误的可能性更小 .

  • 135

    我更喜欢Criteria Queries来进行动态查询 . 例如,根据某些参数,动态添加一些排序或保留一些部分(例如限制)要容易得多 .

    另一方面,我使用HQL进行静态和复杂查询,因为它更容易理解/读取HQL . 另外,我认为HQL更强大,例如对于不同的连接类型 .

    JPA and Hibernate - Criteria vs. JPQL or HQL

  • 3

    你是对的而不是 . 使用 org.hibernate.loader.Loader 类从数据库或缓存中检索结果列表 . 如果未启用缓存,则使用在SessionFactoryImp中创建的Dialect对象构建预准备语句 . 因此,每个列表调用初始化语句 . 此外,自动生成低级查询 . 基本上,它是一种辅助,但可能存在一种情况,当手动编写时,特定查询将更有效 .

相关问题