如何优化外连接查询使其适配Hibernate Criteria使用规范
问题1解答
- 该优化方案完全合理。性能提升的核心原因是你手动做了谓词下推:原查询的执行计划大概率是先对MEASURE、TRADE两张全表做关联,再应用WHERE过滤条件,参与关联的数据集是整张表的全量数据,运算量极大。而改写后的逻辑是先通过子查询把两张表符合过滤条件的极小数据集筛选出来,再用小数据集做关联,参与运算的数据量直接降了几个数量级,执行速度自然会大幅提升。
问题2及替代方案解答
Hibernate Criteria(尤其是低版本)确实不支持直接在FROM子句写子查询,你可以用以下两种方案替代,性能和你手动改写的子查询版本基本持平,同时完全符合Criteria语法要求:
- 新增联合索引后直接用原查询结构
这是成本最低的方案,你只需给两张表加适配查询逻辑的联合索引,数据库优化器会自动做谓词下推,不需要修改查询结构:
- 给
MEASURE表加联合索引:(BOOK_ID, EVENT_CONTEXT, TRADE_ID, BUSINESS_DATE),完全覆盖你的WHERE过滤条件和关联条件,过滤时直接走索引不需要扫全表 - 给
TRADE表加联合索引:(BOOK_ID, BUSINESS_DATE, ID),覆盖关联条件和过滤字段
之后直接用原生的LEFT JOIN写法,用Hibernate Criteria的关联查询API拼接条件即可,性能不会比你手动写子查询的版本差。
- 拆分两次查询(极端场景备选)
如果因为某些原因不能加索引,你可以先用Criteria查符合条件的MEASURE数据,拿到里面的TRADE_ID、BUSINESS_DATE集合,再用Criteria查TRADE表符合条件的数据,最后在内存里做关联拼接,适合关联后返回结果集不大的场景。
额外提醒:你改写后的子查询版本主查询的WHERE条件是重复的,子查询里已经做过一次过滤,主查询不需要再写一遍相同的过滤条件,不影响执行但可以删掉冗余代码。
内容的提问来源于stack exchange,提问作者J.E.Y
相关产品推荐
相关产品推荐

