这是我参与「第四届青训营 」笔记创作活动的第2天
SQL的处理流程
SQL->Parser->AST->Analyzer->Logical Plan -> Optimizer -> Physical Plan -> Executor
Parser
主要是将SQL语句转化为抽象语法树(AST)
- 词法分析
- 语法分析
Analyzer
- 检查并绑定Database,Table,Column等元信息
- SQL的合法性检查,比如min/max/avg的输入为数值
- AST -> Logical Plan(逻辑执行计划)
Logical Plan
逻辑执行计划
- 逻辑地描述SQL对应的分步骤计算操作
- 计算操作:算子(operator)
↓ ↓ ↓ ↓ ↓
Plan Fragment
执行计划子树
- 目标:最小化网络数据传输
- 利用上数据的物理分布(数据亲和性)
- 增加Shuffle算子
将Logical Plan拆分为多个Plan Fragment然后交给Execuor执行
Executor
- 单机并行:cache,pipeline(指令流水线),SIMD
- 多机并行:一个fragment对应多个实例
查询优化器分类
-
Top-down Optimizer 从目标输出开始,由上往下遍历计划书,找到完整的最优执行计划。
-
Bottom-ip Optimizer 从零开始,自下往上遍历计划树,找到完整的执行计划
-
Rule-based Optimizer(RBO) ①根据关系代树等价语义,重写查询
②基于启发式规则
③会访问表的元信息,不会涉及具体的表数据
- Cost-based Optimizer(CBO) ①使用一个模型估算执行计划的代价,选择代价最小的执行计划
RBO
RBO优化规则
- 列裁剪 选出真正用到的列
- 谓词下推 将where条件下推到SCAN阶段,不用join之后再过滤
- 传递闭包 根据join条件,根据等价条件为另一个SCAN阶段创建一个Filter
- Runtime Filter(min-max filter,in-list filter,bloom filter) 只有运行时才能用到,将过滤出来的数据,建立一个hash表,min-max即,表中的最大值和最小值,将该参数返回去另一个SCAN,进行filter,in-list即列出hash表中所有的数,返回另一个SACN中filte
CBO
- 使用一个模型估算执行计划的代价,选择代价最小的执行计划 ①执行计划的代价等于所有算子的执行代价之和
②通过RBO得到(所有)可能的等价执行计划
- 算子代价:CPU、内存、磁盘I/O、网络I/O等代价
统计信息
- 原始表统计信息 ①表或分区级别:行数、行平均大小、表在磁盘中占用了多少字节等
②列级别:min、max、num nulls、num not nulls、NDV、histogram等 2. 推导统计信息
统计信息的收集方式
统计信息推导规则
选择率
NDV:列中独立的互不相同的值的个数
假设列与列之间是独立的,列的值是均匀分布的,这个假设往往是很难成立的