这是我参与「第四届青训营 」笔记创作活动的的第1天
第四届字节跳动青训营大数据专场的第一节课
部分文本资料摘自 ppt课件
SQL 查询优化器浅析
本节课程主要分为 4 个方面:
-
大数据体系和 SQL;
介绍大数据体系和SQL的处理流程,重点介绍SQL在分布式环境下的处理
-
常见的查询优化器;
介绍查询优化器的分类,重点介绍RBO和CBO的原理
-
查询优化器的社区开源实践;
介绍查询优化器在社区的开源实践,重点介绍Apache Calcite项目
-
SQL 相关的前沿趋势。
介绍SQL引擎的前沿趋势,重点介绍AI和DB的结合
1. 大数据体系和 SQL;
SQL的处理流程
在Parser中
- String-> AST(abstract syntax tree)
- 词法分析:拆分字符串,得到关键词、数值常量、字符串常量、运算符号等token
- 语法分析:将token 组成 AST node ,最终得到一个 AST
- 实现: 递归下降(ClickHouse)、Flex和Bison(PostgreSqL),JavaCC(Flink)、Antlr(Presto,Spark)
在Analyzer和Logical Plan中
-
Analyzer
- 检查并绑定 Database,Table,Column 等元信息
- SQL的合法性检查,比如 min/max/avg 的输入是数值;数据库,表和列名是否存在,列的数据类型是否正确
- AST -> Logical Plan
-
Logical Plan
- 逻辑地描述SQL对应分步骤计算操作
- 计算操作:算子(operator)
逻辑计划树的转化(example):
变成
逻辑计划树,可以理解为逻辑地描述一个 SQL 如何一步步地执行查询和计算,最终得到执行结果的一个分步骤地计划。
树中每个节点是是一个算子,定义了对数据集合的计算操作(过滤,排序,聚合,连接),边代表了数据的流向,从孩子节点流向父节点。
之所以称它为逻辑的,是因为算子定义的是逻辑的计算操作,没有指定实际的算法,比如对于逻辑的排序算子,逻辑计划树里没有指定使用快排还是堆排。
在Physical Plan 和Executor 中
-
Plan Fragment:执行计划子树
- 目标:最小化网络数据传输
- 利用上数据的物理分布(数据亲和性)
- 增加Shuffle算子
-
Executor
- 单机并行:cache,pipeline,SIMD
- 多机并行:一个fragment对应多个实例
-
查询优化器是数据库的大脑,在大数据场景下对查询性能至关重要
-
查询优化器需要感知数据分布,充分利用数据的亲和性
-
查询优化器按照最小网络数据传输的目标把逻辑计划拆分成多个物理计划片段
2. 常见的查询优化器
-
Top-down Optimizer
- 从目标输出开始,由上往下遍历计划树,找到完整的最优执行计划
- 例子:Volcano/Cascade,SQLServer
-
Bottom-up Potimizer
- 从零开始,由下往上遍历计划树,找到完整的执行计划
- 例子:System R,PostgreSQL, IBM DB2
-
Rule-based Optimizer(RBO)
- 根据关系代数等价语义,重写查询
- 基于启发式规则
- 会访问表的元信息(catalog),不会涉及具体的表数据(data)
-
Cost-based Optinmizer (CBO)
RBO小结:
- 主流RBO实现一般都有几百条基于经验归纳得到的优化规则
- 优点:实现简单,优化速度快
- 缺点:不保证得到最优的执行计划
CBO小结:
- CBO使用代价模型和统计信息估算执行计划的代价
- CBO使用贪心或者动态规划算法寻找最优执行计划
- 在大数据场景下CBO对查询性能非常重要
3. 社区开源实践
小结:
- 主流的查询优化器都包含RBO和CBO
- Apache Calcite是大数据领域很流行的查询优化器
- Apache Calcite RBO 定义了许多优化规则,使用 pattern 匹配子树,执行等价变换
- Apache Calcite CBO 基于 Volcano/Cascade 框架
- Volcano/Cascade 的精髓: Memo、动态规划、剪枝