Catalyst优化器
Spark SQL使用Catalyst优化所有的查询,包括spark sql和dataframe dsl。这个优化器的使用使得查询比直接使用RDD要快很多。Spark在每个版本都会对Catalyst进行优化以便提高查询性能,而不需要用户修改他们的代码。
ConstantFolding
规则用于移除查询中的常量表达式。
在Spark的早期版本,如果需要添加自定义的优化规则,我们需要修改Spark的源码,这在很多情况下是不太可取的,比如我们仅仅需要优化特定的领域或者场景。所以开发社区想有一种可插拨的方式在Catalyst中添加优化规则。
值得高兴的是,Spark 2.0提供了这种实验式的API,我们可以基于这些API添加自定义的优化规则。本文将介绍如何编写自定义的优化规则,并将这些规则添加到Catalyst中。
dataframe的优化计划(Optimized plan)
在编写我们自定义的优化规则之前,首先我们来理解如何在Spark中访问优化计划,下面代码片段就是展示访问优化计划的:
|
amountPaid
自动乘以1。我们可以使用queryExecution
方法上的optimizedPlan
对象来查看这个DataFrame的优化计划。queryExecution
允许我们访问运行这个查询的所有信息。优化计划就是其中一个。numberedTreeString
方法以树形的方式打印出优化计划。正如上面的输出一样。
所有的计划都是从下往上读的。下面是树中的两个节点:
1、01 Relation:表示从csv文件创建的DataFrame;
2、00 Project:表示投影(也就是需要查询的列)。
cast
将amountPaid
转换成double
类型。
自定义优化计划
amountPaid
乘上1.0
。但是这不是最优计划!因为如果是乘以1,最终的结果是一样的。所有我们可以利用这个知识来编写自定义的优化规则,并将这个规则加入到Catalyst中。
下面代码片段展示了如何自定义优化规则:
|
这里我们扩展了Rule,Rule是直接操作逻辑计划的。绝大多数的规则都是使用Scala中的模式匹配。在上面的代码中,我们首先判断优化的操作数(operand)是否是文字(literal),然后判断其值是否是1.0。为了简便起见,我们限定了1出现的位置,如果1出现在左边,这个优化规则将不起作用。但是我们可以仿照上面的示例轻松地实现。
通过上面的规则,如果右边的值是1,我们将直接返回左边的值。
将自定义的优化规则加入到Catalyst中
上面我们已经定义好自定义的规则,接下来我们需要将这个规则添加到Catalyst中,如下代码片段:
|
experimental
对象,其包含了所有的实验室API。我们可以使用extraOptimizations
来添加一系列的自定义规则到Catalyst中。
使用自定义优化规则
添加好自定义规则之后,我们需要验证这个规则是否启用。如下代码所示:
|
amountPaid
上的乘法已经没了,这证明了我们的优化规则已经起作用了。有了这个强大的可插拨优化规则,将会为开发者提供极大的便利。