sparksql源码系列 | 最全的logical plan优化规则整理(spark2.3)

这篇文章把spark3.2目前用到的所有的逻辑执行计划的优化规则整理了一遍,有需要的点赞收藏,后面用到的时候,就可以随时看啦~~

相关文章:sparksql源码系列 | 生成resolved logical plan的解析规则整理,这一篇是spark3.2最全的logical plan 解析规则整理

整体上分为标准的优化规则和特殊的优化规则,这是为了实现上的扩展性。

  • 标准优化规则

    • 过滤推断前的算子优化-operatorOptimizationRuleSet

    • 过滤推断-Infer Filters

    • 过滤推断后的算子优化-operatorOptimizationRuleSet

    • 下推join的额外谓词-Push extra predicate through join

    • 算子下推(Operator push down)-Project、Join、Limit、列剪裁

    • 算子合并(Operator combine)-Repartition、Project、Window、Filter、Limit、Union

    • 常量折叠和强度消减(Constant folding and strength reduction)-Repartition、Window、Null、常量、In、Filter、整数类型、Like、Boolean、if/case、二义性、no-op、struct、取值操作(struct/array/map)、csv/json、Concat

    • analysis 阶段的收尾规则-Finish Analysis,比如EliminateSubqueryAliases实际是在Analyzer里定义的

    • 算子优化前-Union、Limit、数据库关系、子查询、算子的替代、聚合算子

    • 算子优化-operatorOptimizationBatch

    • 依赖统计数据的优化规则-Project、Filter、Join、Sort、Decimal、Aggregate、对象表达式、数据库关系、笛卡尔积、子查询、Float、Struct

  • 其他特殊的优化规则-分区元数据、DPP(动态分区裁剪)、Filter、Python UDF以及用户自定义的优化规则

​基于spark3.2 branch

rule【规则】 batch【表示一组同类的规则】 strategy【迭代策略】 注释
EliminateDistinct Eliminate Distinct Once 删移除关于MAX和MIN的无效DISTINCT。在 RewriteDistinctAggregates 之前,应该先应用此规则。
EliminateResolvedHint Finish Analysis Once 替换计划中的ResolvedHint算子。将HintInfo移动到关联的Join算子,否则,如果没有匹配的Join算子,就将其删除。HintInfo 是要应用于特定节点的提示属性
EliminateSubqueryAliases Finish Analysis Once 消除子查询别名,对应逻辑算子树中的SubqueryAlias节点。一般来讲,Subqueries 仅用于提供查询的视角范围(Scope)信息,一旦 analysis 阶段结束, 该节点就可以被移除,该优化规则直接将SubqueryAlias替换为其子节点。
EliminateView Finish Analysis Once 此规则将从计划中删除View算子。在analysis阶段结束之前,这个算子会一直受到尊重,因为我们希望看到AnalyzedLogicalPlan的哪一部分是从视图生成的。
InlineCTE Finish Analysis Once 如果满足以下任一条件,则将CTE定义插入相应的引用中:1. CTE定义不包含任何非确定性表达式。如果此CTE定义引用了另一个具有非确定性表达式的CTE定义,则仍然可以内联当前CTE定义。2.在整个主查询和所有子查询中,CTE定义只被引用一次。此外,由于相关子查询的复杂性,无论上述条件如何,相关子查询中的所有CTE引用都是内联的。
ReplaceExpressions Finish Analysis Once 查找所有无法执行的表达式,并用可计算的语义等价表达式替换/重写它们。目前,我们替换了两种表达式:1.RuntimeReplaceable表达式。2.无法执行的聚合表达式,如Every/Some/Any/CountIf 这主要用于提供与其他数据库的兼容性。很少有这样的例子:我们使用它来支持nvl,将其替换为coalesce。我们分别用Min和Max替换each和Any。
RewriteNonCorrelatedExists Finish Analysis Once 为了使用ScalarSubquery需要重写非关联的exists子查询,比如:WHERE EXISTS (SELECT A FROM TABLE B WHERE COL1 > 10) 会被重写成 WHERE (SELECT 1 FROM (SELECT A FROM TABLE B WHERE COL1 > 10) LIMIT 1) IS NOT NULL  。ScalarSubquery是只返回一行和一列的子查询。这将在planning阶段转换为物理标量(scalar)子查询。
PullOutGroupingExpressions Finish Analysis Once 此规则确保Aggregate节点在optimization阶段不包含复杂的分组表达式。复杂的分组表达式被拉到Aggregate下的Project节点,并在分组表达式和不带聚合函数的聚合表达式中引用。这些引用确保优化规则不会将聚合表达式更改为不再引用任何分组表达式的无效表达式,并简化节点上的表达式转换(只需转换表达式一次)。例如,在下面的查询中,Spark不应该将聚合表达式Not(IsNull(c))优化成IsNotNull(c),因为IsNull(c)是一个分组表达式:SELECT not(c IS NULL) FROM t GROUP BY c IS NULL
ComputeCurrentTime Finish Analysis Once 计算当前日期和时间,以确保在单个查询中返回相同的结果。
ReplaceCurrentLike Finish Analysis Once 用当前数据库名称替换CurrentDatabase的表达式。用当前catalog名称替换CurrentCatalog的表达式。
SpecialDatetimeValues Finish Analysis Once 如果输入字符串是可折叠的,则用其日期/时间戳值强制转换成特殊日期时间字符串。
RemoveNoopOperators Union Once 从查询计划中删除不进行任何修改的 no-op 运算符。
CombineUnions Union Once 将所有相邻的Union运算符合并成一个
RemoveNoopUnion Union Once 简化 Union 的子节点,或者从查询计划中删除不修改查询的 no-op Union
OptimizeLimitZero OptimizeLimitZero Once 将GlobalLimit 0和LocalLimit 0节点(子树)替换为空的Local Relation,因为它们不返回任何数据行。
ConvertToLocalRelation LocalRelation early fixedPoint 将LocalRelation上的本地操作(即不需要数据交换的操作)转换为另一个LocalRelation。
PropagateEmptyRelation LocalRelation early fixedPoint 简化了空或非空关系的查询计划。当删除一个Union空关系子级时,PropagateEmptyRelation可以将属性(attribute)的可空性从可空更改为非空
UpdateAttributeNullability LocalRelation early fixedPoint 通过使用其子输出属性(Attributes
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小萝卜算子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值