SQL引擎
参考文档:高级语言的解析过程—解析树
从 MySQL、Oracle、TiDB、CK,到 Hive、HBase、Spark,从关系型数据库到大数据计算引擎,他们大都可以借助 SQL 引擎,实现 “接受一条 sql 语句然后返回查询结果” 的功能。
他们核心的执行逻辑都是一样的,大致可以通过下面的流程来概括。
具体可概括为几个步骤呢?其实无所谓,自己理解就好,粗略点说3、4个,详细点说,也可以是7、8个。
比如:
- 粗略点:解析(Parser)、优化(Optimizer)、执行(Execution)。
- 详细点:
词法解析、语法解析、语义解析生成逻辑执行计划、优化逻辑执行计划优、物理执行计划生成、物理执行计划优化、执行。
共同点
参考网址:
如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1)
(1)解析SQL,生成抽象语法树
概述做什么? 词法分析、语法分析,生成抽象语法树。
详述做什么? 把程序从人类高可读的格式(SQL语句)转换成机器高可读的格式(抽象语法树AST)。
- 词法分析:从SQL语句中识别出词。包括关键字(例如:Select、From、Where)、标识符(字段名、表名等)、操作符(=、>、<)、常量(1、2)等。
- 语法分析:用识别出的词匹配语法规则,校验查询语句是否符合SQL语言的语法规则,比如select from where 等这些关键字是否写对。
校验通过后,会生成一棵抽象语法树(AST),语法树的每个叶子结点都是一个词,AST举例如下。
生成抽象语法树的目的?
保证SQL语句,符合SQL标准的规范。
(2)逻辑执行计划生成和优化
生成:语义分析。
做什么?目的?
- 与元数据绑定。
- 进行有效性检查。检查抽象语法树是否有对应的元数据,生成逻辑执行计划,也即一个Operator(操作符)树(也可称为图),树的叶子结点是一个个的关系代数表达式。
.
该阶段会对表名,字段名、类型等进行检查。
语义分析可以看作包括了语句(statement)分析和表达式(expression)分析。
逻辑执行计划举例如下:
优化:基于规则的优化。常见的有谓词下推、常量合并、列值裁剪等。
(3)物理执行计划生成和优化
物理执行计划是一个task(任务)图。
逻辑执行计划只是逻辑上可执行,引擎并不知道具体如何执行。比如Join算子是一个抽象概念,引擎不知道具体怎么执行。物理执行计划会将其转换成具体地Join,例如MapJoin、ReduceJoin等。
优化:不同引擎,优化方法不同。例如Spark采用Cost Model优化,即最短执行路径。
(4)执行物理计划
最后依据最优的物理执行计划,转换成对应的可执行代码,例如MapReduce程序、DAG程序等。
1 HiveSQL
(1)解析SQL,构建语法树。
词法分析、语法分析
对SQL进行词法分析、语法分析,生成抽象语法树。
(2)逻辑执行计划生成和优化
生成:语义分析,与元数据绑定,生成逻辑执行计划,即一个Operator(操作符)图。
该阶段会对表名,字段名、类型等进行检查。
语义分析可以看作包括了语句(statement)分析和表达式(expression)分析。
优化:基于规则的优化。常见的有谓词下推、常量合并、列值裁剪等。
进而生成逻辑执行计划,即一个操作符树,由操作符构成。
操作符如:TableScanOperator、SelectOperator、FilterOperator、JoinOperator、GroupByOperator和ReduceSinkOperator等。
操作符的作用:这些逻辑操作符可在Map、Reduce阶段完成某一特定操作。
优化逻辑执行计划,合并不必要的操作符。
这里是引用
合并哪些操作符:计算下推、列裁剪、分区裁剪、MapJoin等。
(3)物理执行计划生成和优化
生成物理执行计划,即MapReduce任务。
具体做什么:根据逻辑执行计划的操作符,生成MapReduce任务。
关键点:根据reduceSink操作符划分Stage。作为Map和Reduce的界限,reduceSink之前的作为Map,之后与下一个reduceSink之间的部分作为reduce。
优化物理执行计划,变换MapReduce任务,生成最终的执行计划。
##(4) 执行
将物理执行计划,转换成可执行的代码,提交运行。
2 PrestoSQL
参考文档:
presto 基础和执行过程
Presto 之SQL到Operator转换过程的代码走读
(1)解析SQL,构建语法树。
词法分析、语法分析
对SQL进行词法分析、语法分析,生成抽象语法树。
(2)逻辑执行计划生成、优化、切分
生成:语义分析,与元数据绑定,生成逻辑执行计划,即一个Operator(操作符)图。
该阶段会对表名,字段名、类型等进行检查。
语义分析可以看作包括了语句(statement)分析和表达式(expression)分析。
优化:。
切分:切分逻辑执行计划。
分布式解析,通过exchange切分,生成分布式执行计划树(fragmentedPlan),也叫分发计划。
(3)物理执行计划生成、优化
根据fragmentedPlan中的PlanNode类型(比如上述中的OutputNode)转成对应的Operator(比如TaskOutputOperator)。将这些Operator分发到指定的机器上,分别执行。
(4)执行
将物理执行计划,转换成可执行的代码,提交运行。
3 SparkSQL
参考文档:Spark SQL底层执行流程详解
(1)解析SQL,构建抽象语法树。
词法分析、语法分析
对SQL进行词法分析、语法分析,生成抽象语法树。
(2)逻辑执行计划生成和优化
生成:语义分析,与元数据绑定,生成逻辑执行计划,即一个Operator(操作符)图。
该阶段会对表名,字段名、类型等进行检查。 语义分析可以看作包括了语句(statement)分析和表达式(expression)分析。
优化:基于规则的优化。常见的有谓词下推、常量合并、列值裁剪等。
(3)物理执行计划的生成和优化
优化:基于代价的优化,是计算所有执行路径的代价。先生成多个物理执行计划,然后根据代价模型生成每个计划的代价,最后选取代价最小的作为最终的物理执行计划。
Spark到RDD中间,经过了一个Catalyst。而Catalyst优化器在执行计划生成和优化的工作时候,它离不开自己内部的五大组件,如下所示:
Parser模块:将SparkSql字符串解析为一个抽象语法树/AST。
Analyzer模块:该模块会遍历整个AST,并对AST上的每个节点进行数据类型的绑定以及函数绑定,然后根据元数据信息Catalog对数据表中的字段进行解析。
Optimizer模块:该模块是Catalyst的核心,主要分为RBO和CBO两种优化策略,其中RBO是基于规则优化,CBO是基于代价优化。
SparkPlanner模块:优化后的逻辑执行计划OptimizedLogicalPlan依然是逻辑的,并不能被Spark系统理解,此时需要将OptimizedLogicalPlan转换成physical
plan(物理计划) 。CostModel模块:主要根据过去的性能统计数据,选择最佳的物理执行计划。这个过程的优化就是CBO(基于代价优化)。
(4)执行
将物理执行计划,转换成可执行的代码,提交运行。
4 FlinkSQL
参考文档:
FlinkSQL源码解析(一)转换流程
Flink源码阅读(八)— Flink SQL 整体执行流程
Apache Calcite是一个动态数据管理框架 ,它具备很多典型数据库管理系统的功能,如SQL解析、SQL校验、SQL查询优化等,又省略了一些功能,如不存储相关数据,也不完全包含相关处理数据等。flink中的sql解析、sql校验和sql优化便是依赖calcite来完成的。
(1)解析SQL,生成抽象语法树
词法解析、语法解析,生成抽象语法树
(2)逻辑执行计划生成和优化
生成:语义解析,与元数据绑定,生成逻辑执行计划,即一个Operator(操作符)图。
优化:
(3)物理执行计划生成和优化
生成:
优化:
(4)执行
将物理执行计划,转换成可执行的代码,提交运行。
5 ClickhouseSQL
参考文档:ClickHouse中SQL执行过程
(1)解析SQL,生成抽象语法树
词法分析、语法分析,生成抽象语法树。
(2)逻辑执行计划生成和优化
语义分析,生成逻辑执行计划。
优化:基于规则或基于代价。
(3)物理执行计划生成和优化
生成:依据逻辑执行计划、上下文信息。
优化:基于代价。
(4)执行
将物理执行计划,转换成可执行的代码,并提交执行。