由一条SQL分析SparkSQL执行流程(一)
2018-05-27 本文已影响0人
阿海与蜗牛
现有下面这段SQL语句
SELECT a.uid,b.name,SUM(clk_pv) AS clk_pv
FROM log a
JOIN user b ON a.uid = b.uid
WHERE a.fr = 'android'
GROUP BY a.uid,b.name
这段SQL是从日志表中拿出用户点击PV(clk_pv),再去和用户表关联,按照用户分组,再对点击pv求和,同时,还过滤了fr(平台)是android的数据
这样一条SQL在Spark中或者说在数据库引擎中如何运行?
首先,有几个基本点:
- 所有的编程语言,都是基于操作系统执行。都会被编译(如Java)或被解释(如Python)为操作系统能够按照一定次序执行的命令
- SQL不同于其他编程语言,它是构造在数据库引擎之上的,而数据库引擎又是构造在操作系统之上的,所以,SQL执行的过程是编译成数据库引擎能执行的最优的命令
- 对于用户输入的SQL文本,数据库引擎是通过一种交AST(抽象语法树)进行解析的,实际上是做语法分析
- AST分析目前有很多实现,一种典型的开源实现是ANLTR. Spark SQL 使用的是ANLTRV4 这个版本。
解析的流程
SQL 文本
---> ANLTRV4解析器-->未解析的逻辑计划
---> 分析器 -->解析后的逻辑计划
---> 优化器 -->优化后的逻辑计划
---> 转换器 -->可执行的物理计划
*** SQL解析的思路 ***
解析器的目的是将用户输入的文本,按照预置的关键词,语义等规则解析成一棵 AST。 后续,分析器、优化器,转化器,可对这棵树的节点按照规则遍历,并转换节点结构。
如上图,每个模块都可以理解为,对第一步产生的AST做节点变化操作。
对于最开始提出的SQL,第一步参数的未解析的逻辑计划如下:
image.png
这棵语法数的叶子节点是我们查的两张表,log,user,在往上一层,可看到,实际上是将我们的关联查询解析为两个子查询,再往上一次,是对这两个子查询做join,并按照匹配条件过滤,最后是按照我们所要的聚合条件做聚合投影(projection)
其他问题
- SparkSQL 执行DDL和DML由何区别
- DataFrameWriter执行流程和SQL(create table as select )建表有和不同