查询重写是数据库查询优化的一个重要的阶段,是把一个 SQL 的逻辑树状描述转换成另外一种等价的查询树形式。查询重写的目的是要在转换之后获得语义逻辑表达更为简单的查询树,或者未来能够被查询优化器进行更好的优化的查询树形态。对于查询重写来说,最重要的是保证重写以后查询的结果不变,所以查询重写多是基于关系代数的等价变化,保证重写前后的语义不变。
很多情况下的查询重写是通过某种简单的规则,将符合某种查询形式的查询树进行等价变化,来生成效率更高的查询树。这种重写叫做基于启发式规则的重写。但并不是每种重写都能确保提高查询效率,这时候就需要对重写前的查询和重写后的查询进行查询代价的估计,通过代价竞争来确定使用哪种查询形式。这种通过代价来判断是否进行查询重写,或者使用哪种重写形式的重写叫做基于代价的重写。无论使用哪种重写,都是对查询树进行变换的过程。
OceanBase 的查询重写是基于启发规则式的,仅当根据规则能够判定重写一定会提升查询效率的时候才会启动该重写规则。每一条重写规则都是一个递归的过程,需要遍历查询树以及其所有子树。各个规则的调用顺序和各自递归调用的规则根据各自的功能和所处的位置会有所不同。OceanBase 实现的查询重写规则主要包括七大类:
查询简化
冗余列消除
ANY/ALL 改写
MAX/MIN 消除
外连接消除
视图合并
子查询提升