哪个在hibernate本机查询或HQL中表现更好

时间:2012-08-29 22:25:12

标签: hibernate

在服务器端代码中,为了获得更好的性能,我们不应该使用“select * from table”,而应该根据需要查询必要的列(选择名称,从员工添加)。这是我在数据库性能指南中读到的文章。

现在我对hibernate有一个问题,我读到最好在hibernate中使用session.load(id)来根据主键检索记录。这将检索与给定“id”(表中的记录)的实体关联的所有列。

现在它与一般数据库性能指标并不矛盾。哪个是hibernate本机sql查询或hibernate查询语言更好的性能?

让我知道你的宝贵意见,因为我试图调整我的代码以获得更好的性能。

2 个答案:

答案 0 :(得分:31)

你弄乱了一些部分。您也可以仅使用HQL选择某些列,例如,您可以在HQL中使用select column from table

Native SQL不一定比HQL更快。 HQL最终也被翻译成SQL(您可以在运行show_sql属性设置为true的应用程序时看到生成的语句)。在某些情况下,可能会发生Hibernate不生成最有效的语句,因此本机SQL可以更快 - 但使用本机SQL,您的应用程序会丢失从一个数据库到另一个数据库的可移植性,因此通常更好地调整hibernate映射和HQL语句生成更有效的SQL语句。另一方面,本机SQL缺少Hibernate缓存 - 因此在某些情况下,本机SQL可能比HQL慢。

当您使用session.load(class, id)并且该行尚未在缓存中时,加载也会生成select * from classTable,因此速度与HQL from相同。 (但是当对象已经在缓存中时,那么load可能更快。)

我不同意您的性能指南:在大多数情况下,如果您加载所有列或仅加载所需列,则无关紧要。在数据库访问中,搜索行时会丢失时间,而将数据传输到应用程序时。当您只读取必要的列时,它具有以下缺点:

  • 当您需要尚未加载的列时,更改应用程序会遇到更多麻烦(或者您必须再次加载行,这意味着性能不佳)。
  • 它为您的应用程序提供了一个糟糕的设计(Hibernate更喜欢一个表 - 一个类)
  • 它与Hibernate缓存不兼容。

(想想,如果您的应用程序中有您不需要的列,或者在您的应用程序完成后将添加的列,那么您只是不将它们放入您的类和映射中,它们永远不会加载,你的应用程序设计仍然很好.Hibernate不生成select * from table语句,它总是生成select col1, col2, ... from table。)

有一个例外:如果您加载了大量数据 - 数千行 - 那么只加载必要的列可能会明显加快。

答案 1 :(得分:0)

实体查询(例如JPQL,HQL,Criteria API)再次呈现回SQL查询,因此显然,运行本机SQL查询比运行实体查询要快。

但是,如果将查询计划缓存大小设置为正确,则可以加快实体查询的速度,使其运行速度与SQL一样快。

但是,如果您想从脏检查机制中受益并从修改后的实体自动发出UPDATE,则实体查询会更加方便。只要实体查询和SQL查询之间的时间差不大(通常是使用数据库索引并且实体查询呈现非常有效的SQL查询),就没有什么可担心的。