大数据体系和SQL
这是我参与「第四届青训营 」笔记创作活动的的第1天
本文主要分为4各部分
- 大数据体系和 SQL;
- 常见的查询优化器;
- 查询优化器的社区开源实践;
- SQL 相关的前沿趋势。
SQL 的一生
Parser
把文本变成抽象语法树结构(AST)
涉及词法分析阶段(拆分字符串,提取关键字,字符串,数值等)和语法分析阶段(把词条按照定义的语法规则组装成抽象语法树结构)
和编译原理课程里的“前端”知识相关
Analyzer
访问库/表元信息并绑定
判断 SQL 是否合理,比如数据库,表和列名是否存在,列的数据类型是否正确
将 AST 转换成逻辑计划树(在某些系统中这个工作由一个 Converter 完成)
-
逻辑计划树
- 所谓逻辑计划树,可以理解为逻辑地描述一个 SQL 如何一步步地执行查询和计算,最终得到执行结果的一个分步骤地计划。树中每个节点是是一个算子,定义了对数据集合的计算操作(过滤,排序,聚合,连接),边代表了数据的流向,从孩子节点流向父节点。之所以称它为逻辑的,是因为算子定义的是逻辑的计算操作,没有指定实际的算法,比如对于逻辑的排序算子,逻辑计划树里没有指定使用快排还是堆排。
-
查询优化
-
SQL 是一种声明式语言,用户只描述做什么,没有告诉数据库怎么做
-
查询优化的目标是为 SQL 找到一个正确的且执行代价最小的执行计划
-
查询优化器是数据库的大脑,最复杂的模块,很多相关问题都是 NP 的
-
一般 SQL 越复杂,Join 的表越多,数据量越大,查询优化的意义就越大,因为不同执行方式的性能差别可能有成百上千倍
- 类比 gcc/g++ 编译程序时的编译级别(-O1, -O2, -O3),经过编译优化的程序运行效率更高
-
-
物理执行计划
- 优化器的输出是一个分布式的物理执行计划。
- 分布式物理执行计划的目标是在单机 Plan 的基础上最小化数据移动和最大化本地 Scan,生成 PlanFragment 树。
- 一个 PlanFragment 封装了在一台机器上对数据集的操作逻辑。每个 PlanFragment 可以在每个 executor 节点生成 1 个或多个执行实例,不同执行实例处理不同的数据集,通过并发来提升查询性能。
- Plan 分布式化的方法是增加 shuffle 算子,执行计划树会以 shuffle 算子为边界拆分为PlanFragment。
-
Executor
- Executor 按照物理执行计划扫描和处理数据,充分利用机器资源(CPU 流水线,乱序执行,cache,SIMD)
常见的查询优化器
RBO
Rule-based Optimizer
-
基于关系代数等价规则对逻辑计划进行变换
-
实现上:
- Pattern:定义了特定结构的 Operator 子树(结构)
- Rule:定义了如何将其匹配的节点替换(Substitute)为新形态,从而生成新的、等价的Operator 树(原地替换)
- 优化器搜索过程被抽象为不断匹配 Pattern 然后应用 Rule 转换,直到没有可以匹配的 rule
-
局限性:
- 无法解决多表连接问题
- 无法确定和选择最优的分布式 Join/Aggregate 执行方式
列裁剪
scan时只扫描select选中的列
谓词下推
如有where条件,在scan时就过滤掉
传递闭包
如有jion on条件,可将一个表的where scan 传递给另一个表的 where scan
Runtime Filter(min-max filter,in-list filter,bloom filter)
jion前2个表都有filter,可将一个表filter后的一些索引特性在运行时传递给另一个表,这是另一个表进行filter时就可以减少很大一部分数据
Join 消除
谓词合并
小结
主流RBO实现一般都有几百条基于经验归纳得到的优化规则
实现简单,优化速度块,但不能保证最优的执行计划
CBO
Cost-based Optimizer
过程
使用一个模型估算执行计划的代价,选择代价最小的执行计划
分而治之,执行计划的代价等于所有算子的执行代价之和
通过 RBO 得到(所有)可能的等价执行计划(非原地替换)
算子代价包含 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 行数,在查询计划中常指算子需要处理的行数
统计信息的收集方式
三种
统计信息推导规则
统计信息的问题
小结
CBO使用代价模型和统计信息估算执行计划的代价
CBO使用贪心或者动态规划算法寻求最优执行计划
社区开源实践
Apache Calcite
主流的查询优化器都包含RBO/CBO
Apache Calcite是大数据领域很流行的查询优化器
Apache Calcite RBO定义了很多优化规则,使用pattern匹配子树,执行等价变换
Apache Calcite CBO基于Volcano/Cascade 框架
Volcano/Cascade的精髓Memo、动态规划、剪枝
前沿趋势
存储计算分离
HSAP, HTAP, HTSAP
Cloud Native, Serverless
数据仓库,数据湖,湖仓一体,联邦查询
智能化
-
AI4DB
- 自配置:智能调参(OtterTune,QTune)、负载预测、负载调度
- 自诊断和自愈合:软硬件错误、错误恢复和迁移
- 自优化:统计信息估计( Learned cardinalities )、代价估计、学习型优化器(IBM DB2 LEO),索引推荐,视图推荐
-
DB4AI
- 内嵌人工智能算法(MLSQL,SQLFlow)
- 内嵌机器学习框架(SparkML, Alink, dl-on-flink )