查询优化器(补)|青训营笔记

198 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第 4 天! image.png

1、 常见的查询优化器

查询优化器分类

Top-down Optimizer

  • 从目标输出开始,由上往下遍历计划树,找到完整的最优执行计划

  • 例子:Volcano/Cascade,SQLSever

Bottom-up Optimizer

  • 从零开始,由下往上遍历计划树,找到完整的执行计划

  • 例子:System R,PostgreSQL,IBM DB2

RBO(Rule-based Optimiser)

  • 基于规则优化,采用指定的等价关系代数表达式进行优化。

  • 基于启发式规则

  • 会访问表的元信息,不会设计具体的表数据

CBO(Cost-based Optimiser)

  • 使用模型估算执行计划的代价,选择代价最小的执行计划

*RBO

关系代数

  • 运算符:Select Project Join Rename Union
  • 等价变换:结合律、交换律、传递性

优化规则

  • 读取数据更少更快(I/O)

  • 传输数据更少更快(Network)

  • 处理数据更少更快(CPU & Memory)

一些优化规则:

  • 列裁剪 : 仅扫描所需要的部分列,而不是扫描所有

  • 谓词下推

  • 传递闭包 :根据表达式等价关系,过滤条件,推导出一个新的过滤条件

  • Runtime Filter

对一个join如果能在查询端提早过滤不必要数据,可减少开销

- min-max的缺点:范围必须很紧密
- 
- in-list:只需要扫描in-list里的数据。缺点:集合个数很多时,in-list也很大
- 
- bloom filter:特性:大小不随集合大小改变,固定大小,给一个数可以判断在不在

实现上:

  • Pattern:定义了特定结构的 Operator 子树(结构)

  • Rule:定义了如何将其匹配的节点替换(Substitute)为新形态,从而生成新的、等价的Operator 树(原地替换

  • 优化器搜索过程被抽象为不断匹配 Pattern 然后应用 Rule 转换,直到没有可以匹配的 rule

局限性:

  • 无法解决多表连接问题
  • 无法确定和选择最优的分布式 Join/Aggregate 执行方式

*CBO

graph LR
统计信息+推导规则 --> 计算算子代价 --> 计算执行计划代价 -->执行计划枚举

执行计划的代价等于所有算子的执行代价之和

算子代价包含 CPU,cache misses,memory,disk I/O,network I/O 等代价

  • 和算子的统计信息有关,比如输入、输出结果的行数,每行大小等

  • 叶子算子 scan:通过统计原始表数据得到

    • 中间算子:根据一定的推导规则,从下层算子的统计信息推导得到

    • 和具体的算子类型,以及算子的物理实现有关(e.g. hash join vs. sort join)

基表统计信息

  • 表或者分区级别:行数、行平均大小、表在磁盘中占用了多少字节等
  • 列级别:min、max、num nulls、num、not nulls、num、distinct value(NDV)、histogram 等

推导统计信息

  • 选择率(selectivity) :对于某一个过滤条件,查询会从表中返回多大比例的数据
  • 基数(cardinality) :基本含义是表的 unique 行数,在查询计划中常指算子需要处理的行数

使用贪心或者动态规划算法寻找最优执行计划

2、查询优化器社区开源实践

  • Apache Calcite

  • Orca

  • Volcano/Cascade 框架

    • Memo
    • AND/OR Graph
    • Expression group
    • Group expression
    • Pattern
    • Rule
    • Branch-and-Bound Pruning
    • Winner

3、前沿趋势

  • 存储计算分离

  • HSAP, HTAP, HTSAP

  • Cloud Native, Serverless

  • 数据仓库,数据湖,湖仓一体,联邦查询

  • 智能化:AI4DB,DB4AI