01-SQL 查询优化器浅析 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的第1天
大数据体系
大数据体系如上图所示,主要关注存储系统层,资源调度层,分析引擎以及消息队列。
01-大数据体系和SQL
介绍大数据体系和SQL的处理流程,重点介绍SQL在分布式环境下的处理。
1.1 大数据体系中的SQL
在上图中分析引擎层,Spark中有Spark SQL组件,Flink中也有对应的Flink SQL模块,SQL可以简化用户具体的业务逻辑。但是一些复杂的业务逻辑还是需要Java/Scala SDK来实现。
1.2 SQL处理的流程
SQL语句首先经过Parser模块,然后生成的AST树经过Analyzer模块,经过Logical Plan生成优化之后的执行计划Optimizer,最后通过物理计划Physical Plan生成具体执行器Executor。
1.3 SQL的处理流程-查询优化
逻辑计划进行拆分,只拿到完整执行计划的一部分
一张表的数据可能在多个节点上,每个节点只读取本地的,而不去读取远程的。
Parser模块
将 String 转换为 AST (abstract syntax tree)
- 词法分析:拆分字符串,得到关键词、数值常量、字符串常量、运算符号等token
- 语法分析:将 token 组成 AST node,最终得到一个AST
常见的实现方法有:递归下降(ClickHouse),Flex和Bison(PostgreSQL),JavaCC(Flink),Antlr(Presto,Spark)
Analyzer模块
- 检查并绑定
Database,Table,Column等元信息 SQL的合法性检查,比如min/max/avg的输入是数值AST->Logical Plan
Logical Plan模块
- 逻辑地描述
SQL对应的分步骤计算操作 - 计算操作:算子(
operator)
如何找到一个正确且执行代价最小的物理执行计划?
02-常见的查询优化器
介绍查询优化器的分类,重点介绍RBO和CBO的原理
RBO(Rule-based Optimizer)基于规则
- 根据关系代数等价语义,重写查询
- 基于启发式规则
- 会访问表的元信息(catalog),不会涉及具体的表数据(data)
优化原则:
- 列裁剪
尽可能减少数据
对于一个查询,对应的算子实际上用到的列在计算的时候不需要被读取(保留),尽早去掉这些列,减少IO/内存的占用,为后续优化带来便利。
从上往下扫描,将需要的列往下传递,SCAN时只需要扫描对应的列即可。
- RBO-谓词下推
谓词就是指Where条件里面的表达式,在更早或者更晚的条件下过滤数据,能显著减少计算的开销。
- RBO-传递闭包
创造出一些谓词往下推
根据一些表达式的等价关系推导出新的等价条件
- RBO-传递闭包
创造出一些谓词往下推
根据一些表达式的等价关系推导出新的等价条件
- Runtime Filter
运行时的过滤器,执行时才能产生。min-max, in-list, bloom filter。基于经验无法保证最优。
-
使用一个模型估算执行计划的代价,选择代价最小的执行计划
-
主流RBO实现一般都有几百条基于经验归纳得到的优化规则
-
优点:实现简单,优化速度快
-
缺点:不保证得到最优的执行计划
CBO(Cost-based Optimizer)基于代价
使用一个模型估算执行计划的代价,选择代价最小的执行计划。执行计划的代价等于所有算子的执行代价之和。通过RBO得到(所有)可能的等价执行计划。
算子的代价包括CPU,内存,磁盘I/O,网络I/O。
- CBO使用代价模型和统计信息估算执行计划的代价
- CBO使用贪心或者动态规划算法寻找最优执行计划
- 在大数据场景下CBO对查询性能非常重要
03-社区开源实践
介绍查询优化器在社区的开源实践,重点介绍Apache Calcite项目
- 主流的查询优化器都包含RBO和CBO
- Apache Calcite是大数据领域很流行的查询优化器
- Apache Calcite RBO定义了许多优化规则,使用pattern匹配子树,执行等价变换
- Apache Calcite CBO基于Volcano/Cascade框架
- Volcano/Cascade的精髓:Memo、动态规划、剪枝
04-前沿趋势
介绍SQL引擎的前沿趋势,重点介绍AI和DB的结合
AI加持查询优化,自动调参等。