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

Jan*_*omä 12 java performance hibernate

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

public class Product {


    @OneToMany(fetchType=LAZY)
    @BatchSize(size=10)
    private ProductCategory category;

}
Run Code Online (Sandbox Code Playgroud)

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

Sky*_*kyp 18

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

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

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

通过急切加载某些属性可能会获得更好的性能,因为你总是使用它们,BatchSize对于其他属性你可能需要100,因为你知道它是关于你对该属性的关系数量.

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


mat*_*t b 8

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

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

但是,如果您的应用程序访问product.category一个Product实例时,它不可能访问同一会话category中其他Product实例的字段?如果您已@BatchSize启用该关联,那么您刚刚将许多其他Category实例加载到会话中以获取无效 - 它们将永远不会被使用.