Hibernate提供(至少)两个选项来解决N + 1查询问题。一个是将FetchMode设置为Subselect,这会生成一个带有IN子句的选择以及此IN子句中的子选择。另一个是指定BatchSize,它会生成一个带有包含父母ID的IN子句的选择。
两者都可以工作,但是我发现由于对父项的查询很复杂,Subselect选项经常遇到性能问题。另一方面,对于大的BatchSize(例如1000),查询的数量和这些查询的复杂度非常小。
因此,我的问题是:何时在BatchSize上使用Hibernate的Subselect FetchMode?如果您有大量的父条目(数千个),则Subselect可能有意义,但是在其他情况下,您还是希望Subselect优于BatchSize吗?
编辑:我注意到在处理渴望加载时两者之间的差异。如果您设置了一个xToMany关联集,该关联集将通过子选择快速加载,则它会生成一个子选择,就像它是惰性的一样。但是,如果指定BatchSize,则生成的查询将使用外部联接而不是单独的查询。有什么方法可以强制Hibernate在急切加载时使用单独的批处理查询?
我不使用subselect,因为它很难控制。在具有复杂业务逻辑和庞大团队工作的大型系统中,很难说出使用了哪些查询。在您完全知道执行哪个查询的特定情况下,子选择可能会起作用。
批量读取有一些很大的优点。它并不总是最快的,但通常足够快。另一方面,它非常稳定,没有任何副作用,并且对业务逻辑完全透明。我从来没有使用高于100的批处理值。将N + 1减少到合理数量的查询就足够了。