Hibernate中为何将PASS_DISTINCT_THROUGH提示设为false?
为什么要禁用Hibernate的
PASS_DISTINCT_THROUGH提示? 实际开发中,把QueryHints.PASS_DISTINCT_THROUGH设为false,主要是为了解决特定场景下的正确性或性能问题,并非毫无道理:
关联查询时保证实体去重的正确性
比如查询一对多、多对多关联的主实体时,SQL层面的DISTINCT是基于整行数据去重的。如果用join fetch加载关联子实体,SQL返回的每一行都会因为子实体的不同而重复主实体记录,这时候SQL的DISTINCT根本无法起到去重主实体的作用。而禁用传递后,Hibernate会把所有主实体对象加载到内存,基于实体ID去重,最终得到真正唯一的主实体集合,这才符合业务需求。规避数据库
DISTINCT的性能瓶颈
数据库执行DISTINCT往往需要对结果集排序(如果没有合适的覆盖索引),当数据量较大时,这个操作的开销会非常高。如果查询结果的重复率极低,或者数据库的DISTINCT会触发全表扫描+排序,这时候把数据拉到内存去重的开销反而更小——毕竟内存操作的速度通常比数据库的磁盘IO+排序快得多。适配复杂查询的语义差异
当HQL/JPQL的distinct和SQL层面的DISTINCT语义不匹配时,比如结合了分组、聚合函数的查询,SQL的DISTINCT可能会干扰聚合结果的计算。禁用传递后,Hibernate在内存层面处理实体去重,能保证业务逻辑完全符合HQL/JPQL的语义预期,避免出现意料之外的结果。
内容的提问来源于stack exchange,提问作者mipo256
相关产品推荐
相关产品推荐

