基于规则的Spark SQL Catalyst优化器(三)

公众号:浮世Talk(逍遥浮世,与道俱成。人来人往,与君共勉。

上一篇文章中我们主要讨论了Replace Operators、Aggregate和Operator Optimisation的一部分规则,这篇文章将继续讨论剩下的优化器批次规则,首先继续对Operator Optimization批次规则进行讲解。

Batch – Operator Optimization

CollapseRepartition

CollapseRepartition规则结合了相邻的repartition运算符。有过spark开发经验的都知道,repartition函数和coalesce函数均可以用来改变数据集的分区数量。repartition函数可以用来增加或减少分区,从而达到shuffle的目的,而coalesce函数只能用来减少分区的数量,而这些分区不能实现shuffle。

当一个非shuffle Repartition(coalesce)操作符有一个shuffle Repartition操作符的子级操作符时,如果父集操作符的numPartitions更大,则返回子级操作符:

如果shuffle Repartition的numPartition更大,则保持两个Repartition操作符不变:

当一个RepartitionByExpression操作符有一个Repartition或RepartitionByExpression的子级操作符时,移除该子级操作符。

CollapseProject

collapseProject规则结合了两个投影操作符。如下面的例子所示,两个投影操作符被合并为一个:

Combine Operators

考虑到以下规则的工作方式类似,我将一并解释它们。

  • CombineFilters

  • CombineLimits

  • CombineUnions

那些组合运算符规则通过合并运算符的条件将两个相邻的运算符合并为一个。

CombineFilters规则通过使用AND逻辑合并两个过滤器操作符的过滤条件,将两个相邻的过滤器合并为一个。

CombineLimits规则合并了两个相邻的Limit运算符,并使用较小的limit值。

CombineUnions规则合并了所有的Union操作符。

Constant Evaluation

下面的规则主要用于处理常数,所以我把它们放在一起:

  • NullPropagation

  • ConstantPropagation

  • OptimizeIn

  • ConstantFolding

  • ReorderAssociativeOperator

  • ReplaceNullWithFalseInPredicate

  • CombineConcats

NullPropagation规则根据数据类型,用相等的值来等价替换Null值。

ConstantPropagation规则用可以在联合表达式中等价的值来替换一个属性。以下面的查询为例,过滤条件第二部分的id属性,order_id = 100 + id,可以用第一部分的id值来替代。

OptimizeIn规则用于优化IN谓词。当IN值列表中存在重复值时,重复的部分将被删除。

此外,如果IN值列表的大小大于预定的阈值,IN运算符将被替换为INSET运算符,后者的速度会快很多。

ConstantFolding规则对表达式进行评估,并将其替换为等价的Literal值。

RecorderAssociativeOperator规则首先对关联的整型运算符进行重新排序,然后将所有常数折叠(fold)成一个。

nullvalue(空值)在一个谓词中被评估为false。ReplaceNullWithFalseInPredicate规则将空值替换为false。

CombineConcats规则结合了嵌套的concat表达式。

Operator Simplication

The following rules are mainly used for simplifying operators:

以下规则主要用于简化运算符。

  • LikeSimplification

  • BooleanSimplification

  • SimplifyConditionals

  • SimplifyBinaryComparison

  • PruneFilters

  • SimplifyCasts

  • SimplifyCaseConversionExpressions

  • RewriteCorrelatedScalarSubquery

  • EliminateSerialization

  • RemoveRedundantAliases

  • SimplifyExtractValueOps

LIKE表达式可以用来在谓词中匹配一个完整的正则表达式的字符串。当要匹配的模式不需要完整的正则表达式时,例如'%abc'(用于startsWith条件)或'abc%'(用于endsWith条件),LikeSimplification规则可以用更快的StartsWith或EndsWith表达式替换Like表达式。

BooleanSimplification规则简化了谓词中的布尔表达式。当一个谓词由多个布尔表达式部分组成时,如果一个表达式部分可以在不评估其他部分的情况下被确定,该谓词可以被简化。

当一个过滤条件由常数组成并且可以在优化阶段确定时,SimplifyConditionals会移除条件并直接返回结果(由条件决定)。

当二元比较的结果可以在优化阶段确定时,SimplifyBinaryComparison规则将二元比较表达式替换为语义上相等的真或假表达式

The PruneFiltersrule removes the filters that can be evaluated trivially.

PruneFilters规则删除了可以被琐碎地评估的过滤器。

当要转换的值的数据类型与预期的数据类型相同时,SimplifyCasts规则将不必要的转换表达式删除。

当一些表达式可以在优化阶段被评估和解决时,SimplifyCaseConversionExpression规则会移除大小写转换表达式。

RewriteCorrelatedScalarSubquery规则将相关的ScalarSubquery表达式重写为LEFT OUTER连接。

优化后的查询可以用下面的方式表示:

EliminateSerialization规则消除了不必要的序列化或反序列化操作。例如,在下面的查询中,连续的map操作会有一个SerializeFromObject操作,紧接着一个DesericalizeToObject操作。由于在第一个map操作和第二个map操作之间的节点不需要进行数据交换,所以中间的序列化/反序列化操作是不必要的,可以被删除。

当一个别名不改变列的名称或元数据时,这个别名是多余的,对查询没有用处。removeRedundantAliases规则会从逻辑计划中删除多余的别名。

当查询所需的值可以直接提取时,SimplifyExtractValueOps规则会删除不必要的数据结构创建。

Array数据结构的例子:

Map数据结构的例子:

Named_Struct数据结构的例子:

Batch – Early Filter and Projection Push-Down

这个批次是一个占位符,用于将过滤器和投影推送到扫描节点的规则。

Batch – Join Reorder

这个批次包括CostBasedJoinReorder规则,它是一个基于成本的优化器规则(cost-based Optimizer rule),用于根据连接中涉及的关系的统计数字找到最有效的连接顺序。

Spark SQL中成本模型背后的基本思想是计算Spark Planner生成的所有候选物理计划的成本,然后选择成本最低的一个。然而,在Spark 3.0.0之前,成本模型尚未实现。相反,在逻辑计划优化阶段应用CostBasedJoinReorderrule。要启用此规则,请使用spark.sql.cbo.enabledflagspark.sql.cbo.joinReorder.enabledflag需要设置为true。

CostBasedJoinReorder规则收集join操作中涉及的关系的统计数据,计算所有有效连接组合的成本,并使用预定义的成本公式找到最佳连接组合。

Batch – Eliminate Sorts

这个批次包括EliminateSorts规则,它删除了必要的Sort运算符。

Batch – Decimal Optimizations

这个批次是用来优化小数计算的。在Spark 3.0.0中,本批中包括一条规则,DecimalAggregates。DecimalAggregates规则,如果可能的话,在内部将小数转换为未缩放的Long值。使用未缩放(unscaled)的十进制的Long值预计会加速聚合计算。

Batch – Object Expressions Optimization

本批包括与数据集API的对象操作有关的优化器规则,包括。

  • EliminateMapObjects--如果输入和输出的类型是原始类型,且不可置空,没有指定数据项的自定义集合类表示,则消除MapObjects操作。

  • CombineTypedFilters - 将两个相邻的TypedFilters合并为一个。

  • ObjectSerializerPruning - 删减不必要的对象序列化器

  • ReassignLambdaVariableID - 为LambdaVriables重新分配每个查询的唯一ID,这样可以更频繁地访问codegen缓存。

Batch – LocalRelation

LocalRelation批次将被执行两次,第一次执行是在执行主要优化器规则之前,第二次执行是在之后。第一批执行已经在之前的博文:基于规则的Spark SQL Catalyst优化器(一)中解释过了,主要是简化逻辑计划以避免潜在的重度优化器规则。这是第二批执行,它整理了由空的局部关系组成的逻辑计划。空的局部关系是由"Operator Optimization"批次中的PruneFilters规则产生的。因此,这个批次的执行时间在"Operator Optimization"批次之后。

Batch – Check Cartesian Products

这个批处理包括CheckCartesianProducts规则,它检查一个join操作是否是一个笛卡尔的乘积。当CROSS_JOIN_ENABLED标志被设置为false时,如果join是一个笛卡尔乘积,则抛出一个错误。

Batch – RewriteSubquery

该批次包括以下优化器规则,这些规则也包括在之前执行的"Operator Optimization"批次中。

  • RewritePredicateSubquery

  • ColumnPruning

  • CollapseProject

  • RemoveNoopOperators

这些规则的另一次运行可以优化"Operator Optimization"批量执行后产生的operators 。

Batch – NormalizeFloatingNumbers

该批处理包括normalizeefloatingnumbers规则,该规则处理特殊的浮点数(例如NaN和0.0/-0.0)。在这种情况下,不同的NaNs需要被视为相同,并且“0.0”和“-0.0”需要也被视为相同,包括值比较、聚合分组键、连接键和窗口分区键。

 

- THE END -

 

公众号:浮世Talk

逍遥浮世,与道俱成。人来人往,与君共勉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值