我该如何解决N+1查询问题?

7

我有困难理解如何在jpa或hibernate中避免n+1查询问题。

据我所读,有“左连接提取”,但我不确定它是否仍适用于多个列表(oneToMany)..

有人能向我解释一下,或给我一个清晰完整的解释链接吗?

如果这是一个初学者的问题,我很抱歉,但我找不到一个真正清晰的文章或文档来解决这个问题。

谢谢


理解这个问题对于使用Hibernate非常关键。我甚至开发了一个小的库,在单元测试中识别此问题:https://github.com/bedrin/jdbc-sniffer/ - bedrin
1个回答

8
除了join之外,您还可以使用子查询。这将导致执行2个查询(或通常情况下是m+1个查询,如果您有m个列表),但对于大量的列表来说,它扩展得很好,不像联接获取。
使用联接获取时,如果您使用实体提取2个表(或列表),则会获得笛卡尔积,即来自两个表的行对的所有组合。如果表很大,则结果可能是巨大的,例如如果两个表都有1000行,则笛卡尔积包含100万行!
这种情况的更好替代方案是使用子查询。在这种情况下,您将针对主要选择(加载父实体)发出2个选择 - 每个表一个选择,因此总共使用3个查询加载1 + 100 + 100行。
记录一下,与延迟加载相同,将导致201个单独的选择,每个选择加载一行。
更新:以下是一些示例:
- 教程:调整延迟提取,其中包含有关子查询的部分(顺便说一句,它还解释了n + 1选择问题及其处理的所有策略), - Hibernate参考文献中的HQL子查询示例, - 以防万一,Hibernate参考文献中有关获取策略的章节 - 与第一个内容类似,但更加详细。

2
你能提供一个子查询解决方案的简短HQL示例吗?我认为这会帮助我理清思路。谢谢 :) - Maxime ARNSTAMM
@Maxime 我添加了一些链接,希望这些能有所帮助 :-) - Péter Török

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接