SparkSQL的执⾏流程(附常量折叠、谓词下推、列裁剪案
例)
1、RDD 和 SparkSQL 运⾏时的区别:
和 RDD 不同, SparkSQL 的 Dataset 和 SQL 并不是直接⽣成计划交给集执⾏, ⽽是经过了⼀个叫做 Catalyst 的优化器, 这个优化器能够⾃动帮助开发者优化代码。
2、SparkSQL 的执⾏流程:
1、Parser转换器,第三⽅类库 Antlr 实现。将 sql 字符串切分成 Token,根据语义规则解析成⼀颗AST语法树,称为Unresolved Logical Plan 未解决的逻辑计划;
简单来说就是判断 SQL 语句是否符合规范,⽐如select from where 这些关键字是否写对。就算表名字段名写错也⽆所谓。
2、Unresolved Logical Plan经过Analyzer分析器,借助于表的真实数据元数据 schema catalog,进⾏数据类型绑定和函数绑定,解析为 resolved Logical Plan 已解决的逻辑计划;
sql语句优化方式简单来说就是判断 SQL 语句的表名,字段名是否真的在元数据库⾥存在。
3、Optimizer优化器,基于各种优化规则(常量折叠,谓词下推,列裁剪),将上⾯的resolved Logic
al Plan进⼀步转换为语法树Optimized Logical Plan 优化的逻辑计划。这个过程称作 RBO(Rule Based Optimizer 基于规则的优化))。
简单来说就是把可执⾏的SQL 再调整⼀下,以便跑得更快。
4、query planner 查询计划器,基于 planning 计划过程,将逻辑计划转换成多个物理计划,再根据代价模型 cost model,筛选出代价最⼩的物理计划。这个过程称之为 CBO(Cost Based Optimizer 基于成本的优化)。
上⾯2-3-4步骤合起来,就是 Catalyst 优化器。
5、最后依据最优的物理计划,⽣成 java 字节码,将 SQL 转换为 DAG,以 RDD 形式进⾏操作。
3、Catalyst 的两⼤优化:
3.1 RBO:基于规则的优化,⽐如谓词下推,列裁剪,常量折叠。
常量折叠案例:
select 1+1 as id from table1
会优化为(会提前将 1+1 计算折叠成 2,再赋给 id 列的每⾏,不⽤每⾏都计算⼀次 1+1)
select 2 as id from table1
谓词下推案例:
select * from table1 ajoin table2 b on a.id=b.idwhere a.age>20and b.cid=1
会优化为(在⼦查询阶段就提前将数据进⾏过滤,后期 join 的 shuffle 数据量就⼤⼤减少)
select * from ( select * from table1 where age>20) ajoin (select * from table2 where cid=1) b on a.id=b.id
列裁剪案例:
select a.name, a.age, b.cidfrom (select * from table1 where a.age>20) ajoin (select * from table2 where b.cid=1) b on a.id=b.id
会优化为(提前将需要的列查询出来,其他不需要的列裁剪掉)
select a.name, a.age, b.cidfrom (select name,age,id from table1 where a.age>20) ajoin (select
id,cid from table2 where b.cid=1) b on a.i CBO:基于代价的优化,多种物理计划基于cost model,选取最优的执⾏耗时最少的那个物理计划。
4、explain参看逻辑计划和物理计划:
SparkSQL中的DSL⽅式:
spark.sql('select count(1) from test_db.table1').explain(True)
普通SQL⽅式:
explain extended select count(1) from table1;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论