【问题标题】:Hibernate : fetch lazy collection with HQLHibernate:使用 HQL 获取惰性集合
【发布时间】:2016-04-08 23:48:37
【问题描述】:

我有两个大表(每个 > 1 亿行),我们称它们为 Parent 和 Child(Parent 与 Child 具有惰性的一对多关系)。当我使用连接提取时查询很慢 而且我还收到一个休眠警告“HH000104 firstresult maxresults specified with collection fetch applied in memory”,因为我使用了限制。

所以我试图在两个单独的查询中获取数据:
- 第一个查询获取所有父母的限制
- 第二个查询在第一个查询找到的父 ID 中获取具有 parent.id 的子代

此解决方案执行得非常好,但是 hibernate 不会将子项与其父项聚合,尽管这两个查询是在同一个会话中执行的。

我想知道是否有办法使用 HQL 或一些 java 代码来实现这一点: - 我不希望使用标准 API(我需要重写许多查询,并且我发现标准 API 查询难以维护) - 我不想将父/子关系更改为 EAGER/BATCH,因为没有子我将无法查询父

有什么想法吗?

【问题讨论】:

    标签: java hibernate hql


    【解决方案1】:

    第二个查询不应该只获取子节点:Hibernate 无法知道每个父节点的所有子节点都已获取。

    第二个查询应该得到父母和他们的孩子(但使用in 子句只选择所需的父母,并且没有限制):

    第一个查询,应用了限制:

    select distinct p.id from Parent p where ... 
    

    第二次查询,无限制:

    select p from Parent p left join fetch p.children where p.id in :idsSelectedByTheFirstQuery
    

    【讨论】:

    • 感谢您的快速回答。使用此解决方案,第二个查询的性能很差。因为孩子有父 ID,我希望我可以将它们加载到单独的查询中并将它们分组到会话中......
    • 为什么表现不佳?它的性能不应该比只选择子级的查询差得多,除非您在子级和父级之间的连接列上没有索引。现在,只要您发布您的代码和 DDL,我们就不必猜测所有内容。
    • 只有当表有数百万行时才会出现性能问题,因此还需要数据库来重现它。我希望有一个“简单”的解决方案来组装不需要类和代码的 bean……我使用 postgresql,但我无法从执行计划中找出查询出了什么问题获取父母和孩子。当然,父表和子表之间有一个索引。我的猜测是查询返回更多数据,因为每个父母至少有两个孩子,所以获取两个意味着返回每个父母两次......
    • @JDM 应该没有理由它的执行速度比您建议的要慢得多。您最初的建议类似于from Child where parent.id in :idsSelectedByTheFirstQuery。生成的 SQL 的区别只是父子表的连接,如果你有适当的索引,即使有百万条记录也不应该是什么
    猜你喜欢
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 2017-11-25
    • 2013-11-24
    • 2013-02-15
    • 1970-01-01
    相关资源
    最近更新 更多