这是我参与「第四届青训营 」笔记创作活动的的第5天
前言:上节对sql处理流程中的Analyzer、Optimizer以及Executor进行了记录,本节将记录sql Optimizer中常见的查询优化器,继续加油吧!🥳
常见的查询优化器分为:RBO (Rule-based Optimizer)和CBO (Cost-based Optimizer)。
按照规则分为
Top-down Optimizer
- 从目标输出开始,由上往下遍历计划树,找到完整的最优执行计划
- 例子:Volcano/Cascade,SQLServer
Bottom-up Optimizer
- 从零开始,由下往上遍历计划树,找到完整的执行计划
- 例子:System R,PostgreSQL,,IBM DB2
RBO (Rule-based Optimizer)
根据关系代数等价语义,重写查询
基于启发式规则
会访问表的元信息(catalog),不会涉及具体的表数据(data)
即可以使用等价变换:结合律,交换律,传递性
RBO优化原则
- Read data less and faster (I/o)
- Read data less and faster (I/o)
- Process data less and faster (CPU & Memory)
列裁剪
对于以下sql语句:
SELECT pv.siteld, user.name FROM pv JOIN user ON pv.siteld = user.siteld AND pv.userld = user.id WHERE user.siteld >123;
其优化的逻辑计划如下:
解释:对于需要用到的列(siteid,userid,id,name等)在进行表扫描的时候就只进行这几列的扫描,而不是把所有列都扫描进来,然后等到FILTER时再过滤掉。当一个表拥有很多列数据时(几百列只用到其中的几列)这样可以减少读取的数据。
谓词下推
对于以下sql语句:
SELECT pv.siteld, user.name FROM pv JOIN user ON pv.siteld = user.siteld AND pv.userld = user.id WHERE user.siteld >123;
即在扫描user表的时候直接筛选出 siteid>123的数据,然后再进行JION操作
传递闭包
对于以下sql语句:
SELECT pv.siteld, user.name FROM pv JOIN user ON pv.siteld = user.siteld AND pv.userld = user.id WHERE user.siteld >123;
由pv.siteld = user.siteld和 user.siteld >123可以得出需要的pv.siteld 也应该大于123 因此在扫描pv表的时候直接筛选出 siteid>123的数据,然后再进行JION操作