连接查询的休眠性能问题

Posted

技术标签:

【中文标题】连接查询的休眠性能问题【英文标题】:Hibernate performance issues with join queries 【发布时间】:2012-01-28 04:53:54 【问题描述】:

我们正在使用动态 HQL 查询生成器,它生成如下查询:

select sum(en1.amount) from SampleEntity1 as en1 where en1.child.name = ?    

Hibernate 会将上述查询转换为 sql,如下所示:

select sum(tbl1.c_amount)  from sampletable1 as tbl1, samplechild as child1 where tbl1.c_child = child1.c_id and child1.c_name = ?

表 sampletable1 和 samplechild 都有超过 100 万条记录,并且由于生成的 sql 有交叉连接,查询的性能非常低,并且会遭受大量的数据库 I/O。 但是如果我们使用内连接运行 sql,查询的性能会更好。

有什么方法可以强制休眠将此类 HQL 查询转换为内部联接而不是交叉联接?

【问题讨论】:

您愿意给 Batoo JPA 一个机会吗? Batoo JPA 是新的 JPA 实现,性能提高了 15 倍。 batoo.jp 【参考方案1】:

这是一个内连接,但它没有使用内连接语法。如果您希望使用内连接语法,请使用内连接,如 Hibernate reference manual 中所述:

select sum(en1.amount) from SampleEntity1 as en1 
inner join en1.child child
where child.name = ?   

我很惊讶这两个查询不会同时执行。它们是等效的,并且应该使用相同的索引。

【讨论】:

感谢您的回答,但我想强制休眠将 en1.child 转换为 sql 查询,例如 sampletable1 as tbl1 inner join samplechild as child on child.tbl1_fk = tbls1.id 是的。这正是我回答中的查询所做的。 我更改了我的 HibernateDialect,现在一切正常,所有查询都转换为内部联接。 @JBNizet 两个查询在数据库上同时执行,但是hibernate在得到结果后使用反射(在交叉连接的情况下)。

以上是关于连接查询的休眠性能问题的主要内容,如果未能解决你的问题,请参考以下文章

带有连接的休眠自定义 SQL 查询 - 避免返回数组列表

如何使用具有多个连接的 SQL 查询并使用休眠计数

休眠 HQL 连接错误

休眠 SQL 错误:17002,SQLState:空 Io 异常:连接重置

返回休眠本机 sql 查询

如何配置 Hibernate Envers 以避免实体修订查询中的某些集合(连接表)