为什么我不会在每个延迟加载的关系中使用@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
实例而无法获得 – 它们将永远不会被使用。