16

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

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

现在是不是与一般数据库性能指南相矛盾。hibernate native sql 查询和hibernate 查询语言哪个性能更好?

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

4

2 回答 2

43

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

原生 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。)

有一个例外:如果您加载大量数据(数千行),那么仅加载必要的列会明显更快。

于 2012-08-30T09:11:18.853 回答
2

实体查询(例如 JPQL、HQL、Criteria API)再次被渲染回 SQL 查询,因此很明显,运行原生 SQL 查询将比运行实体查询更快。

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

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

于 2019-06-26T07:10:30.547 回答