sql执行计划源码探索

执行流程

大致的流程是这样的,先记好每个阶段,我们来一起探索每个阶段在哪里,又做了什么

代码入口

入口在SparkSession类,里面有一个lazy  sessionState,里面很多对象都是lazy懒加载,在最后使用时程序全部执行

首先会调用.sql()

sqlParser解析sql语句

SQL语句(字符串)传递给sessionState.sqlParser,调用parsePlan()把一个sql字符串语句解析为一个抽象语法树(Spark称此阶段为Unresoved logicPlan)

这个阶段是基于ANTLR实现,期间会校验关键字和语法

Analyzer解析

然后SparkSession.sessionState.analyzer对象,走到Analyzer类

调用executeAndCheck()把Unresoved logicPlan转为 Analyzed logicPlan

这个类也有一些规则需要执行,主要在batch里面

另外这个阶段还做了几件事,特别重要的有这几个:

  1. 关联元数据,校验字段函数表
  2. 数据类型绑定及函数绑定
  3. 类型推断

比如dt = dateadd('2024-01-01',1)在这阶段转换为 cast(dt as date) = dateadd(cast('2024-01-01' as date),1),analyzer在最后会调用一个规则,其中就包含类型转换,TypeCoercionBase 记录了转换的规则,string优先级很低

optimizer

接着传递给sessionState.optimizer

这个阶段主要是基于RBO的规则优化,主要对sql优化,比较重要的有这几个

  1. 谓词下推(Predicate Pushdown) ,比如下图语法树变为先过滤后join
  2. 常量累加(Constant Folding) ,100+80在此步骤优化为180,不会在每条数据都执行100+80
  3. 列值裁剪(Column Pruning),只会扫描需要的列,优化网络传输,内存和扫描效率

SparkPlan

传递给sessionState.planner,SparkPlan类

--------------------------------

此阶段有一个 strategies 非常值得深入学习,另外顺便看下SparkPlan的继承关系,很多人都搞不清SparkPlan是什么,PhysicalPlan是什么

-----------------------回到正题

SparkPlanner的继承关系。生成物理计划的策略保存在Strategies属性下。plan()方法是生成物理计划的入口,将strategies依次应用到LogicalPlan,生成物理计划候选集合。对于PlanLater类型的 SparkPlan,其doExecute()方法没有实现,表示不支持执行,所起到的作用仅仅是占位作用。SparkPlanner会取出所有的PlanLater算子,递归调用plan()方法进行替换。之后,调用prunePlans()方法对物理计划列表进行过滤,去掉一些不够高效的物理计划 。在生成SparkPlan列表后,调用prepareForExecution()根据需要插入shuffle操作和格式转换以适应Spark执行,主要工作是检查是否有不匹配的partition类型,如果不兼容就增加一个Exchange节点,用来重新分区,这样就最终生成了execute plan

查询规划器生成的物理计划会被传递给sessionState.prepareForExecution,它会进行额外的优化,比如重新排序join操作等。

最后,经过所有处理的物理计划会被提交给SparkSession.sparkContext,在Spark集群上执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

orange大数据技术探索者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值