SparkSQL逻辑计划概述
逻辑计划阶段被定义为LogicalPlan类,主要有三个阶段:
- 由SparkSqlParser中的AstBuilder将语法树的各个节点转换为对应LogicalPlan节点,组成未解析的逻辑算子树,不包含数据信息与列信息
- 由Analyzer将一系列规则作用在未解析逻辑算子树上,生成解析后的逻辑算子树
- 有Optimizer将一系列优化规则应用在逻辑算子树中,确保结果正确的前提下改进低效结构,生成优化后的逻辑算子树
LogicalPlan简介
概述
LogicalPlan的父类QueryPlan主要分为六个模块:
– 输入输出 涉及QueryPlan内属性相关的输入输出
– 基本属性 QueryPlan内的基本属性
– 字符串 主要用于打印QueryPlan的树形结构信息
– 规范化 类似Expression中的规范化
– 表达式操作
– 约束 本质上也是数据过滤条件的一种,同样是表达式类型。通过显式的过滤条件推导约束
基本操作和分类
- LeafNode 主要对应数据表和命令相关逻辑。
- RunnableCommand 直接运行的命令 包括相关Database相关,Table相关,View相关,DDL相关,Function和Resource相关命令
- UnaryNode 常见与对数据的逻辑转换操作,如过滤等
- 用来重定义分区操作(RedistributeData) 主要针对现有分区和排序的特定不满足的场景
- 脚本相关的转换操作(ScriptTransformation) 用特定脚本对输入数据进行转换
- Object相关操作(ObjectConsumer)
- 常见操作算子(basicLogicalOperators) 涉及Project,Filter,Sort等各种常见关系算子
- BinaryNode 常见于对数据的组合关联操作
- 连接(Join)
- 集合
- CoGroup
- 其他类型
- Union 是一系列LoginPlan列表
- ObjectProducer 用于产生只包含Object列的行数据
- EventTimeWatermark 针对Spark Streaming中的水印机制
AstBuilder机制:Unresolved LogicalPlan生成
从visitSingleStatement
为入口从根部递归访问整棵树,当访问到某个子节点可以构造LogicalPlan时,然后传递到父节点;执行到QuerySpecificationContext时,首先访问FromClauseContext子树,生成from的LogicalPlan,然后调用withQuerySpecification
在from的基础上完成扩展
从访问QuerySpecificationContext开始,主要分为以下三个步骤
- 生成数据表对应的LogicalPlan: 访问FromClauseContext直到匹配TableNameContext节点时,根据其中的数据信息生成UnresolvedRelation,并跳出递归,构造名为from的LogicalPlan
- 生成加入了过滤逻辑的LogicalPlan:对BooleanDefaultContext进行递归,生成对应的expression并返回作为过滤条件,然后基于此生成Filter LogicalPlanjiedian ,并与(1)中的UnresolvedRelation构造withFilter的LogicalPlan
- 生成加入列剪裁后的LogicalPlan: 获取QuerySpecificationContext节点所包含的NamedExpressionSeqContext成员,并对其所有子节点表达式进行转换,生成NameExpression列表,然后生成Project LogicalPlan,并与(2)中的withFilter构造withProject的LogicalPlan