SQL Optimizer | 青训营笔记

82 阅读3分钟

这是我参与「第四届青训营」笔记创作活动的的第1天

SQL处理流程

1. Parser

   String————————>token————————>AST(语法树)
          词法分析       语法分析

2. Analyzer

    AST——————————>Logical Plan(算子的排序而非如何执行)
        Analyzer
     (检查绑定元信息)

3. Optimizer

    决定性能
    目标:最小化网格数据传输
    Logical Plan——————————>Physical Plan(Plan Fragment)

4. Executor

    单机并行
    多机并行

Optimizer分类

一、

  1. Top-down Optimizer 从目标输出开始,上至下遍历计划树,找完整最优执行计划
  2. Bottom-up Optimizer 从零开始,下至上,找完整执行计划

二、

  1. RBO
    等价语义-->重写查询
    基于启发式规则得到计划
    会访问元信息,不涉及表数据
  2. CBO 使用一个模型估算执行计划的代价,基于代价择优
  • 一半情况RBO可以找到最优解,无需CBO
  • 另一半中大部分有CBO性能较高
  • 大数据下CBO※

RBO

减少工作量,快,实现简单,基于经验得到(不保证最优)

一、

1. 关系代数

  • 运算符(可拆分):select、 project、 join......
  • 等价变换:结合律、交换律、传递性

2. 优化原则-少且快-按重要性可配比

  • I/O
  • Network
  • cpu/Memory

3. 列裁剪

只扫描需要的 table student ————> student(sid, sname)

4. 谓词下推

谓词就是返回boolean值即true和false的函数,或是隐式转换为bool的函数
SQL中的谓词主要有 LKIE、BETWEEN、IS NULL、IS NOT NULL、IN、EXISTS
将过滤表达式尽可能移动至靠近数据源的位置,以使真正执行时能直接跳过无关的数据。 从计算进程下推到存储进程先行执行、以减少开销

谓词下推条件?
如果在表达式中含有不确定函数,整个表达式的谓词将不会被pushed,例如

select a.* 
from a join b on a.id = b.id
where a.ds = '2019-10-09' and a.create_time = unix_timestamp();

因为unix_timestamp是不确定函数,在编译的时候无法得知,所以,整个表达式不会被pushed,即ds='2019-10-09'也不会被提前过滤。类似的不确定函数还有rand()等。1

5. 传递闭包

6. Runtime Filter

二、缺点

1. 单表扫描:

    索引扫描(随机I/O)  
                vs  全表扫描(顺序I/O)

2. Join实现:

    Hash Join  
              vs SortMergin Join

3.两表Hash Join

用小表构建Hash表-->如何识别小表

4.多表

最优?每种组合都探索?

CBO

解决RBO缺点
统计信息 + 推导规则 ——>计算算子代价、计划代价——>执行计划枚举

1.统计信息

  • 统计信息的准确与否会影响CBO做出最优的选择
  • 原始表统计信息(表/分区级别,列级别) ——> 推导统计信息(选择率、基数※)
  • 收集方式:
      1. 写入时 (操作多,慢,影响写入效率)
      1. 手动执行 (执行前的数据是过时的)
      1. 动态采样 (select count(*) from table )

2. 推导规则

列独立、值均匀分布 (此假设与实际很不符-->指定或识别相关联的列、直方图)

  • and : fs(a and b) = fs(a) * fs(b)
  • or : fs(a or b) = fs(a) + fs(b) - fs(a) * fs(b)
  • not : fs(not a) = 1 - fs(a)
  • x = i : i < min && i > max ? 0 : 1/NDV (利用均匀分布)(NDV不同数的个数)
  • x < i : i < min --> 0 ; i > max --> 1 ; (i - min)/(max - min) (利用均匀分布得到选择率)

3.执行计划枚举

贪心/动规 (比较代价)

社区开源实践

273f4e35085d490b29a9efbb9dbeb84.jpg 参考文献:

(129条消息) 一篇搞懂谓词下推_EdwardsWang丶的博客-CSDN博客_谓词下推