Hive优化器原理与源码解析系列--优化规则ProjectOverIntersectRemoveRule(九)
目录
背景
优化规则ProjectOverIntersectRemoveRule
matches方法逻辑详解
onMatch方法逻辑详解
总结
背景
这篇文章来Hive优化规则ProjectOverIntersectRemoveRule,此优化规则的主要功能是把操作符树中INTERSECT交集操作符的之上的Project投影操作符,在满足一定条件下,把Project投影操作符移除减少执行计划的执行成本。
Hive CBO基于成本优化器原理与源码解析的系列文章都是基于Hive 2.3.3版本的,支持Intersect操作符(因为Hive 1.X不支持Intersect操作符),讲解ProjectOverIntersectRemoveRule才有意义。
从SQL角度讲,带有INTERSECT交集、 PROJECT投影的这种SQL语句写法中,如果Project投影中的RexNode表达式和Intersect交集操作符中RexNode行表达式的个数和数据类型完全一致,则将Intersect之上的Project投影操作符移除。
举例说明:
SELECT key, value, ds FROM (
SELECT key, value, ds FROM src_intersect_1
INTERSECT
SELECT key, value, ds FROM src_intersect_2
INTERSECT
SELECT key, value, ds FROM src_intersect_3
) subq ;
为了说明方便,使用了SQL进行讲述,其实优化器内部使用的RelNode关系表达式构造的操作符树组成来构建的。从操作符树角度来看,最外层的Select就是顶层的Project投影操作,内部的表src_intersect_1、src_intersect_1和src_intersect_1之间的Intersect操作就是指底部的INTERSECT操作符。
变换后的SQL表示为:
SELECT key, value, ds FROM src_intersect_1
INTERSECT
SELECT key, value, ds FROM src_intersect_2
INTERSECT
SELECT key, value, ds FROM src_intersect_3;
说明:因为Project投影的字段key, value, ds和Intersect的字段key, value, ds字段个数和数据类型完全相同,因此把重复的顶层的Project操作移除掉。
Hive几乎所有优化规则Rule继承了父类RelOptRule。关于RelOptRule和RelOptRuleCall相关概念。这里不再赘述,详细翻阅前期文章。
优化规则ProjectOverIntersectRemoveRule
此优化规则的matches判断方法和OnMatch等价转换部分都相对比较简单。
因为matches和OnMatch两个方法是每条优化规则的关键,这里还是做一些两个方法的简要说明
1)matches方法逻辑详解
matches方法返回此规则Rule是否可能与给定的操作数operands匹配,但是此方法的任何实现都可以给出误报,也就是说虽然规则与操作数匹配,但随后具OnMatch(ReloptRuleCall)而不生成任何后续任务。
call.rel(0)表示为顶层为Project投影,call.rel(1)表达为顶部的Intersect交集,isTrivial函数是判断project和intersect是否完全一致,包含字段个数和字段的数据类型返回boolean值。
public boolean matches(RelOptRuleCall call) {
Project project = call.rel(0);
Intersect intersect = call.rel(1);
return isTrivial(project, intersect); //判断project和intersect字段个数和数据类型是否完全一致。返回true,完全一致。可以移除
}
isTrivial方法实现,是比较Project和Intersect操作符的的字段,RexUtil.isIdentity返回表达式列表是否投影传入字段
private static boolean isTrivial(Project project, Intersect intersect) {return RexUtil.isIdentity(project.getProjects(), intersect.getRowType());
}
RexUtil.isIdentity方法源码实现:
public static boolean isIdentity(List<? extends RexNode> exps,
RelDataType inputRowType) {
return inputRowType.getFieldCount() == exps.size()
&& containIdentity(exps, inputRowType, Litmus.IGNORE);
}
2)onMatch方法逻辑详解
接收有关一条规则匹配的通知。同时此方法被调用,call.rels保存了与规则Rule的操作数Operands匹配上的关系表达式RelNode集合;call.rels[0]是根表达式。通常一条规则Rule会检查这些节点是否有效匹配,创建一个新表达式RelNode(等价的)然后调用RelOptRuleCall.transformTo(org.apache.calcite.rel.RelNode, java.util.Map<org.apache.calcite.rel.RelNode, org.apache.calcite.rel.RelNode>)注册表达式。而RelOptRuleCall用一系列RelNode关系表达式集合作为参数,对RelOptRule优化规则的调用。
public void onMatch(RelOptRuleCall call) {
call.transformTo(call.rel(1));
} //如果Project和Intersect字段相同,则移除Project
此条优化规则的onMatch方法设计相对简单,满足了matches判断后,直接跳过表示为顶层的Project投影call.rel(0),直接把call.rel(1) Intersect操作符注册到等价集合。这样意味着把Project进行移除。
总结
优化规则ProjectOverIntersectRemoveRule相对比较简单,简单的matches方法判断满足顶部为Project投影操作符,底部为Intersect交集操作符,并两者的字段个数和数据类型完全一致,使用call.transformTo(call.rel(1))跳过顶部Project投影,把Intersect交集操作符注册到等价集合,达到Project投影移除来进行优化目的。
由于笔者知识及水平有限,因此文中错漏之处在所难免,恳请各位老师、专家不吝赐教。
往期文章分享
优化规则系列
Hive优化器原理与源码解析系列--优化规则SortRemoveRule(一)
Hive优化器原理与源码解析系列--优化规则SortJoinReduceRule(二)
Hive优化器原理与源码解析系列--优化规则SortProjectTransposeRule(三)
Hive优化器原理与源码解析系列--优化规则SortUnionReduceRule(四)
Hive优化器原理与源码解析系列--优化规则SortMergeRule(五)
Hive优化器原理与源码解析系列--优化规则ProjectFilterPullUpConstantsRule(六)
Hive优化器原理与源码解析系列--优化规则SortLimitPullUpConstantsRule(七)
Hive优化器原理与源码解析系列--优化规则UnionPullUpConstantsRule(八)
成本模型系列
Hive优化器原理与源码解析系列—统计信息带谓词选择率Selectivity
Hive优化器原理与源码解析系列--统计信息中间结果大小计算
Hive优化器原理与源码解析系列—CBO成本模型CostModel(一)
Hive优化器原理与源码解析系列—CBO成本模型CostModel(二)
Hive优化器原理与源码解析系列—统计信息UniqueKeys列集合
Hive优化器原理与源码解析—统计信息Parallelism并行度计算