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

时间:2013-07-02 08:18:57

标签: java performance hibernate

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

public class Product {


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

}

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

2 个答案:

答案 0 :(得分:18)

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

简短的回答是:你不应该进行优先购买。

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

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

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

答案 1 :(得分:8)

  

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

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

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