15

Hibernate 提供(至少)两个选项来解决 N+1 查询问题。一个是将 FetchMode 设置为 Subselect,它会生成一个带有 IN 子句的选择和一个在该 IN 子句中的子选择。另一种是指定一个 BatchSize,它生成一个带有包含父母 ID 的 IN 子句的选择。

两者都有效,但我发现 Subselect 选项经常遇到性能问题,因为对父母的查询很复杂。另一方面,对于较大的 BatchSize(例如 1000),查询的数量和这些查询的复杂性都非常小。

因此,我的问题是:你什么时候会在 BatchSize 上使用 Hibernate 的 Subselect FetchMode?如果您有大量的父条目(数千个),那么 Subselect 可能是有意义的,但是在其他情况下,您是否更喜欢 Subselect 而不是 BatchSize?

编辑:在处理急切加载时,我注意到两者之间的区别。如果您将 xToMany 关联设置为急切地加载并通过子选择,它会生成一个子选择,就像它是惰性的一样。但是,如果您指定 BatchSize,则生成的查询将使用外连接而不是单独的查询。有什么方法可以强制 Hibernate 在急切加载时使用单独的批处理查询?

4

2 回答 2

14

我不使用子选择,因为它很难控制。在一个非常大的系统中,它具有复杂的业务逻辑和一个庞大的团队,很难说使用了哪些查询。子选择可能在您确切知道执行哪个查询的特定情况下工作。

批量获取有一些很大的优势。它并不总是最快的,但通常足够快。另一方面,它非常稳定,没有任何副作用,对业务逻辑完全透明。我从不使用高于 100 的批处理值。将 N+1 减少到合理数量的查询就足够了。

于 2011-08-30T06:28:10.317 回答
2

我发现这篇文章很有帮助。我相信批量提取可以应用于集合和父级,而子选择只能应用于集合。

在集合的获取策略的情况下,子选择将执行一次(因为批量大小实际上是无穷大的),而对于批量获取,SQL 语句可能会执行多次。

于 2012-06-29T12:11:45.393 回答