SQL Optimizer 解析 | 青训营笔记

107 阅读3分钟

SQL Optimizer 解析 | 青训营笔记

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

1.大数据体系和SQL

大数据体系中的SQL

SQL是十分重要的

One SQL rules big data all 我们希望能用SQL处理所有的大数据

SQL的处理流程

image.png

  1. Parser
    • String-->抽象语法树(AST)
    • 词法分析:拆分字符串,得到关键词、数值常量、运算符号等token
    • 语法分析:把token按规则组装成抽象语法树(AST)
  2. Analyzer
    • 检查并绑定DB、Table、Column等原信息
    • SQL的合法性检查
    • AST-> Logical Plan 逻辑计划树
  3. Logical Plan
    1. image.png
    2. 逻辑地描述一个SQL如何一步步执行查询和计算
    3. 树中每个节点是是一个算子,定义了对数据集合的计算操作(过滤,排序,聚合,连接),边代表了数据的流向,从孩子节点流向父节点。
  4. 查询优化
    • 目标是为 SQL 找到一个正确的且执行代价最小的执行计划
    • 是后文重点介绍的部分
  5. Physical Plan
    1. image.png
    2. 优化器的输出是一个分布式的物理执行计划
  6. Executor

2.查询优化器

2.1查询优化器的分类

  • Top-down Optimizer
  • Bottom-up Optimizer
  • Rule-based Optimizer(RBO): 根据关系代数等价语句,重写查询
  • Cost-based Optimizer(CBO): 选择最小代价

2.2 RBO

2.2.1 原理

  • 基于关系代数等价规则对逻辑计划进行变换
    • Pattern:定义了特定结构的 Operator 子树(结构)
    • Rule:定义了如何将其匹配的节点替换(Substitute)为新形态,从而生成新的、等价的Operator 树(原地替换
    • 优化器搜索过程被抽象为不断匹配 Pattern 然后应用 Rule 转换,直到没有可以匹配的 rule

2.2.2 优化原则Rule:

  • 列裁剪: 不需要的去掉,只扫描需要的列
  • 谓词下推: 数据的提前过滤 eg: where语句先实现
  • 传递闭包: 通过表达式的等价关系和过滤条件->新的过滤条件
  • Runtime Filter:
    • min-max, in-list(0-100, 1000000) 102个数, bloom filter

2.2.3 小结

  1. 主流RBO 几百条基于经验归纳得到的优化规则
  2. 实现简单,优化速度快
  3. 不保证得到最优的执行计划

2.3 CBO

概念

  • 使用代价模型统计信息估算执行计划的代价
  • step1:通过 RBO 得到(所有)可能的等价执行计划
  • step2:使用一个模型估算执行计划的代价,选择代价最小的执行计划
  • 算子代价:CPU、内存、磁盘I/O、网络I/O等代价

2.3.1 CBO-统计信息

  • 原始表统计信息
    • 表或者分区级别:行数
    • 列级别:min、max、num nulls、num not nulls等
  • 推导统计信息
    • 选择率(selectivity):对于某一过滤条件,查询从表中返回数据的比率
    • 基数(cardinality):算子需要处理的行数
  • 统计信息的收集方式 3种
  • 统计信息推导规则

2.3.2 CBO-执行计划枚举

  • 贪心算法/动态规划
    • 动态规划示例
  • 在大数据场景下,CBO对查询性能是很重要的

3.社区开源实践 - Apache Calcite

3.1 Apache Calcite RBO

  • HepPlanner
  • Rule:使用pattern匹配表达式子树、等价变换得到新的表达式

3.2 Apache Calcite CBO

  • VolcanoPlanner
  • 基于Volcano/Cascade框架
  • 三点精髓:
    • 1.Memo
      • 存储候选候执行计划
      • 应用Rule搜索候选计划
      • Memo本质:AND/OR graph 共享子树减少内存开销
    • 2.Top-down 动态规划搜索
    • 3.剪枝:减少搜索空间
      • 已搜索完成的物理计划的代价最小值成为 Cost Upper Bound。当新的搜索分支的代价高于它时,不需继续搜索