SQL Optimizer 解析 | 青训营笔记

115 阅读3分钟

SQL Optimizer 解析 | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第1天,本篇笔记主要是关于第一次大数据课程《SQL Optimizer》的课堂笔记


大数据体系

image.png

SQL的处理流程

image.png

  • parser:SQL语句(string类型)作为输入,输出AST(abstract syntax tree-抽象语法树)
    1. 语法分析:拆分字符串,得到关键字、数值常量、字符串常量、运算符号等token
    2. 词法分析:将token组成AST node,最终得到AST

AST示意图image.png

  • Analyzer:AST作为输入,输出Logical Plan-逻辑执行计划(逻辑地描述SQL对应的分步骤计算操作 计算操作:算子)
    1. 检查并绑定Database,Table,Column等元信息
    2. SQL的合法检查
  • Optimizer:查询优化,找到一个正确且代价最小的物理执行计划 Plan Fragment:执行计划子树
  1. 目标:最小化网络数据传输
  2. 利用数据的物理分布(数据亲和性)(数据分布在多个结点上,每个节点最好只读本地数据)
  3. 增加shuffle算子(shuffle算子:用于连接结点)
  • Executor:
    1. 单机并行:cache,pipeline,SIMD
    2. 多机并行: 一个fragment对应多个实例

  • 查询优化器分类: 根据遍历方向:
1. Top-down Optimizer:从目标输出开始,从上往下遍历计划树,找到完整的最优执行计划
2. Bottom-up Optimizer:从零开始,由下往上遍历计划树,找到完整的执行计划

根据优化方法:

1. RBO(Rule-based Optimizer):
    根据关系代数等价语义,重写查询
    基于启发式规则(根据经验)
    会访问表的元信息,不会涉及具体的表数据
2. CBO(Cost-based Optimizer):
    使用一个模型估算执行计划的代价,选择代价最小的执行计划
    算子代价:CPU,内存,磁盘I/O,网络I/O等代价

RBO:

  • 关系代数基础:

image.png

  • 优化原则:
    1. 优化I/O:读更少的数据/更快的读取数据
    2. 优化网络:传输更少的数据/更快的传输数据
    3. 优化CPU&内存:处理的数据更少、更快
  • 几种策略:
    1. 列裁剪:一个查询对应的算子,实际上用不到的列并不需要读取/保留,所以应尽早地去掉这些列,从而减少对I/O或内存地占用,实现地时候会从上往下进行扫描。
    2. 谓词下推:谓词指代where中的表达式。若我们提前过滤数据不会导致最终结果出错,就今早过滤。
    3. 传递闭包:根据表达式的等价关系以及过滤条件,可以推导出新的过滤条件
    4. Runtime Filter select pv.siteId, user.name from pv join pv.siteId = user.siteId and pv.userId = user.Id where user.siteId > 123;

列裁剪:image.png 谓词下推:image.png 传递闭包:image.png Runtime Filter:image.png

  • 小结:
    1. 主流RBO实现一般都有几百条基于经验归纳得到的优化规则
    2. 优点:实现简单,优化速度快
    3. 缺点:不保证得到最优的执行计划 CBO:
  • 流程:
graph TD
统计信息+推导规则 --> 计算算子代价 --> 计算执行计划代价 --> 执行计划枚举
  • 统计信息:
    • 原始表统计信息
    • 推导统计信息:
      1. 选择率(selectivity):对于某一个过滤条件,查询会从表中返回多大比例的数据
      2. 基数(cardinality):在查询计划中常指算子需要处理的行数
  • 小结:
    1. CBO使用代价模型和统计信息估算执行计划的代价
    2. CBO使用贪心或动态规划算法寻找最优执行计划
    3. 在大数据场景下CBO对查询性能非常重要