SQL查询优化器浅析 | 青训营笔记

237 阅读4分钟

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

01.大数据体系和SQL

image.png

SQL受欢迎:多个大数据计算引擎都支持 SQL 作为更高抽象层次的计算入口。

One SQL rules big data all.

SQL执行流程:

image.png

Parser(解析器) :语句->AST(抽象语法树)

词法分析阶段(拆分字符串,提取关键字,字符串,数值等)

语法分析阶段(把词条按照定义的语法规则组装成抽象语法树结构)

实现方法:递归下降,Flex和Bison,JavaCC,Antlr。

Analyzer(分析) :合不合理啊?

访问库/表元信息并绑定

判断 SQL 是否合理,比如数据库,表和列名是否存在,列的数据类型是否正确

AST ->逻辑计划树

逻辑计划树(Logical Plan):

逻辑地描述一个 SQL 如何一步步地执行查询和计算。树中每个节点是是一个算子(过滤,排序,聚合,连接),边代表了数据的流向,从孩子节点流向父节点。

Physical Plan (物理执行计划)

优化器的输出是一个分布式的物理执行计划

目标:利用数据物理分布(数据亲和性),提前决策,最小化网络数据传输

方法:增加 shuffle 算子

Executor(执行器)

Executor 按照物理执行计划扫描和处理数据,充分利用机器资源

(重点)查询优化

为啥优化?SQL没有告诉数据库怎么做,而能达到目的的不同的执行方法差异较大;

目标?找到代价最小的执行计划;

重要的点?查询优化器很大程度上决定了数据库的性能,是数据库的大脑,数据越多,查询优化的意义就越大。

02.常见的查询优化器

查询优化器的分类(两种分类方法):

根据树的遍历顺序:自上而下、由下往上。

根据优化的参考:根据关系代数(RBO)、根据代价模型(CBO)

RBO-优化原则:

  • I/O方面-读的数据更少更快

  • Network方面-传输的数据更少更快

  • CPU方面-指令数更少

RBO-优化方法:

  • 列裁剪(至上而下扫描并记录要用的列,然后舍弃不用的列)

  • 谓词下推(缩小范围的动作先执行)

  • 传递闭包(将缩小范围的谓词以及过滤条件推导出其余缩小范围的谓词)

  • 运行时过滤(在运行时自己总结一边的数据范围,另一边做选择时受到影响)

RBO小结: 实现简单优化速度快,但不一定能得到最优的执行计划,选择很多,基于经验。

CBO概念:

通过RBO得到等价执行计划,模型估算执行计划的代价,选择代价最小的执行计划。

image.png 算子代价:

和算子的物理实现、类型有关。叶子算子Scan通过原始数据得到,中间算子根据一定的推导规则从下层算子推导得到。

CBO-统计信息:

  • 基表统计信息:

表或者分区级别:行数、行平均大小、表在磁盘中占用了多少字节等

列级别:min、max、num nulls、num not nulls、num distinct value(NDV)、histogram 等

  • 推导统计信息

选择率(selectivity):对于某一个过滤条件,查询会从表中返回多大比例的数据

基数(cardinality):基本含义是表的 unique 行数,在查询计划中常指算子需要处理的行数

CBO-统计信息收集方式(为了收集基本信息): 在DDL里指定、手动执行分析、动态采样

CBO-统计信息推导规则(为了计算推导信息): 概率论的应用

CBO-执行计划枚举:通常使用贪心算法或动态规划选出最优的执行计划

03.社区开源实践

本部分带我们了解RBO和CBO的实际使用。

image.png

Apache Calcite是一个很流行的查询优化器:模块化、插件化、稳定可靠、支持异构数据模型(如关系型、半结构化、流式、地理空间数据)

Calcite RBO: 优化速度快,实现简单,但是不保证最优

Calcite CBO: 基于Volcano/Cascade框架

Volcano/Cascade的精髓: Memo数据结构、动态规划、剪枝

04.前沿趋势

Big Data, Big Money.

image.png

引擎架构的进化、云、湖仓一体对SQL查询优化器有新的要求和挑战。AI加持,学习型查询优化器在不断进化。