这是我参与「第四届青训营 」笔记创作活动的的第6天
前言:上节对sql Optimizer中常见的RBO查询优化器进行了记录,本节将记录sql Optimizer中常见的CBO查询优化器,由于在公司实习,学习速度有点慢😥,明天会push自己多看一些大数据课程,加油鸭🥳
CBO
首先看一下CBO的概念:使用一个模型估算执行计划的代价,选择代价最小的执行计划
- 执行计划的代价等于所有算子的执行代价之和
- 通过RBO得到(所有)可能的等价执行计划
算子代价包括:CPU,内存,磁盘I/O,网络I/O等代价
-
算子代价和算子输入数据的统计信息有关:输入、输出结果的行数,每行大小...
√叶子算子Scan:通过统计原始表数据得到
√中间算子:根据一定的推导规则,从下层算子的统计信息推导得到
-
算子代价和具体的算子类型,以及算子的物理实现有关
例如:Spark Join算子代价= weight * row count+ (1.0 - weight)* size
因此,CBO可以概括为下图:
CBO-统计信息
- 原始表统计信息
- 表或者分区级别:行数、行平均大小、表在磁盘中占用了多少字节等
- 列级别: min、max、num nulls、num not nulls、num distinct value(NDV)、histogram等
- 推导统计信息
- 选择率(
selectivity):对于某一个过滤条件,查询会从表中返回多大比例的数据 - 基数(
cardinality):在查询计划中常指算子需要处理的行数
注意:准确的cardinality远比代价模型本身重要!
CB0-统计信息的收集方式
- 在DDL里指定需要收集的统计信息,数据库会在数据写入时收集或者更新统计信息
- 手动执行explain analyze statement,触发数据库收集或者更新统计信息
- 动态采样
CBO-统计信息的推导规则
即FILTER的基数(处理行数)等于对A的基数进行Selectivity过滤
在进行推导时需要注意以下问题