为什么我不会在每个延迟加载的关系中使用@BatchSize?

hibernate的@BatchSize注释允许批量提取延迟加载的实体。 例如,如果我得到类似的东西:

public class Product { @OneToMany(fetchType=LAZY) @BatchSize(size=10) private ProductCategory category; } 

现在,如果我得到产品的类别,Hibernate将获取最多十个产品的类别,这些产品在当前会话中并且尚未初始化其类别字段。 这节省了大量SQL调用数据库。 到现在为止还挺好。 现在我想知道为什么我不会在每个懒惰的加载关系上使用@BatchSize注释? 毕竟为什么我要额外调用数据库? 显然必须有这个原因,否则Hibernate的人可能会把它作为默认,但我目前看不到它。

我不会直接回答你的问题,但我会回答一个更通用的问题,可能是“我发现了一些对我来说更快的东西,为什么不在任何地方应用呢?”

简短的回答是:你不应该做抢先优化。

hibernate是一个很棒的ORM,可以进行各种优化。 您应该测量导致问题的所有过程(即使是快速的经典N + 1 ,任何缓慢的过程等)并进行优化以解决它。

通过急切加载某些属性可能会获得更好的性能,因为您总是使用它们,您可能需要将BatchSize为100,因为您知道它与您对该属性的关系数量有关。

最终,您不应该关心优化,除非您需要关心它。 当您完成测量并发现问题时,您需要关心。

为什么我不会在每个懒惰的加载关系上使用@BatchSize注释?

因为它是一种优化,您可能不需要在每种情况下。 当您的应用程序要访问许多不同products product.category ,这样的批量提取很有用,因此您可以select from category...一个select from category...查询执行而不是N个。

但是,如果您的应用程序访问一个Product实例的product.category ,则不太可能访问同一会话中其他Product实例的category字段? 如果您为该关联启用了@BatchSize ,那么您刚刚在会话中加载了许多其他Category实例而无法获得 – 它们将永远不会被使用。