SparkSQL逻辑计划概述

逻辑计划阶段被定义为LogicalPlan类,主要有三个阶段:

  1. 由SparkSqlParser中的AstBuilder将语法树的各个节点转换为对应LogicalPlan节点,组成未解析的逻辑算子树,不包含数据信息与列信息
  2. 由Analyzer将一系列规则作用在未解析逻辑算子树上,生成解析后的逻辑算子树
  3. 有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开始,主要分为以下三个步骤

  1. 生成数据表对应的LogicalPlan: 访问FromClauseContext直到匹配TableNameContext节点时,根据其中的数据信息生成UnresolvedRelation,并跳出递归,构造名为from的LogicalPlan
  2. 生成加入了过滤逻辑的LogicalPlan:对BooleanDefaultContext进行递归,生成对应的expression并返回作为过滤条件,然后基于此生成Filter LogicalPlanjiedian ,并与(1)中的UnresolvedRelation构造withFilter的LogicalPlan
  3. 生成加入列剪裁后的LogicalPlan: 获取QuerySpecificationContext节点所包含的NamedExpressionSeqContext成员,并对其所有子节点表达式进行转换,生成NameExpression列表,然后生成Project LogicalPlan,并与(2)中的withFilter构造withProject的LogicalPlan