Oceanbase查询改写:谓词移动
概述
当查询语句中存在谓词时,能够减少执行阶段需要处理的数据量。为此,Oceanbase中定义了谓词移动规则,能够利用查询语句中各部分已有的谓词推导出新的谓词,并将其尽可能下推至数据读取阶段,从而减少各阶段需要处理的数据量,提升查询性能。
基本原理
SELECT * FROM
(SELECT * FROM t1 WHERE c2 < 1000) v1,
(SELECT * FROM t2 WHERE c2 > 0) v2
WHERE v1.c1 = v2.c1 AND v1.c2 > v2.c2 AND v1.c1 > 0;
对于上述查询,可以对其进行谓词推导和下推改写,从而减少需要读取的数据量,如下所示:
SELECT * FROM
(SELECT * FROM t1 WHERE c1 > 0 AND c2 > 0 AND c2 < 1000) v1,
(SELECT * FROM t2 WHERE c1 > 0 AND c2 > 0 AND c2 < 1000) v2
WHERE v1.c1 = v2.c1 AND v1.c2 > v2.c2;
代码解析
谓词移动规则的入口为ObTransformPredicateMoveAround::transform_one_stmt,执行流程如下:
- 调用pullup_predicates函数对满足条件的视图表或集合子查询中的谓词执行提升收集。
- 调用pushdown_predicates函数对父查询中的谓词结合前一步收集的谓词执行下推。
pullup_predicates函数负责递归地将视图表中的谓词收集到集合中,执行流程如下:
- 调用acquire_transform_params函数为当前语句分配谓词集合(下称input_pullup_preds),供后续流程使用。
- 如果当前语句为集合语句,则执行如下流程进行处理:
- 调用pullup_predicates_from_set函数对集合语句子查询中的谓词进行提升收集。
- 调用generate_set_pullup_predicates函数提取pullup_preds中能够向上提升的谓词(即涉及的参数列均位于集合语句的select列表中的谓词),用于返回父查询。
- 调用acquire_transform_params函数获取为当前语句分配的谓词集合,将收集到的谓词保存到该集合中。
- 如果当前语句不为集合语句,则执行如下流程进行处理:
- 调用preprocess函数将semi信息及join表中能够提升的条件移动到当前语句的where条件中。
- 调用pullup_predicates_from_view函数将当前语句的视图表中的谓词收集到input_pullup_preds中。
- 如果当前语句为视图查询语句或集合子查询,则调用generate_pullup_predicates函数结合当前语句的where条件、having条件及input_pullup_preds中的谓词进行推导,将得到的谓词集合返回父查询。