目录
背景
优化规则HiveFilterSortTransposeRule
- matches方法逻辑详解
- onMatch方法逻辑详解
总结
背景
这篇文章来讲优化规则HiveFilterSortTransposeRule,主要功能是Filter操作和SortLimit操作位置调换或Filter操作下推到HiveSortLimit操作之下,此规则也属于Filter过滤器下推的一种,只是下推到Sort排序操作之下,都是提前过滤掉不必要的数据,减少排序算力的浪费,以达优化目的。操作符树等价变换如下:
其中,上述提到的HiveSortLimit排序类是对Calcite Sort关系表达式继承,在不改变其内容的情况下,对其输入强制执行特定的排序顺序(对排序完整描述)。
代码语言:javascript复制public Sort(RelOptCluster cluster,
RelTraitSet traits,
RelNode child,
RelCollation collation,
RexNode offset,
RexNode fetch)
创建 Sort对象.
- 参数
cluster
- 运行环境traits
- 特征集合,是否排序,是否为分布式物理特征child
-输入的关系表达式RelNodecollation
- 排序说明,排序字段、升序或降序等等offset
- 在返回记录前抛弃的记录数fetch
- 返回的记录数
强调说明的是,在Hive中,含有Order By和Sort By语句都是HiveSortLimit来实现的。
优化规则HiveFilterSortTransposeRule
1)matches方法逻辑详解
matches方法返回此规则Rule是否可能与给定的操作数operands匹配,但是此方法的任何实现都可以给出误报,也就是说虽然规则与操作数匹配,但随后具OnMatch(ReloptRuleCall)而不生成任何后续任务。
判断由RelOptCall调用的优化规则Rule是否与输入参数RelNode关系表达式匹配,即此优化规则Rule能否应用到一个RelNode关系表达式树上。
HiveSortLimit类,是对为Hive SQL语句中Sort和Order两种不同操作的实现类,此matches方法中,如果排序含有Limit语句,则退出优化。
代码语言:javascript复制public boolean matches(RelOptRuleCall call) {
final HiveSortLimit sort = call.rel(1);
// If sort contains a limit operation, we bail out
if (HiveCalciteUtil.limitRelNode(sort)) {//如果排序含有Limit语句,则退出优化
return false;
}
return true;
}
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优化规则的调用。
首先,call.rel(0)获取HiveFilter过滤器对象和call.rel(1)获取HiveSortLimit对象。
谓词下推主要分两个步骤:
- 使用sort的输入sort.getInput()创建新Filter对象newFilter,意味着在Sort的子输入上创建过滤器,完成了Fitler下推到TableScan上。此时Filter从操作符树上看,在TableScan数据源之上。
- 再使用新Filter对象newFilter,创建新SortLimit操作,即newFilter下推SortLimit操作之下。
以上完成了Filter操作下推到SortLimit操作之下。
代码语言:javascript复制public void onMatch(RelOptRuleCall call) {
final HiveFilter filter = call.rel(0);//根 RelNode
final HiveSortLimit sort = call.rel(1);
final RelNode newFilter = filter.copy(sort.getInput().getTraitSet(),//保留了Sort输入的特征集合
ImmutableList.<RelNode>of(sort.getInput()));//使用Sort的输入创建Filter
final HiveSortLimit newSort = sort.copy(sort.getTraitSet(),
newFilter, sort.collation, sort.offset, sort.fetch);//创建SortLimit对象
call.transformTo(newSort);
}
总结
优化规则HiveFilterSortTransposeRule将Filter操作下推到SortLimit操作之下,此规则也属于Filter过滤器下推优化的一种。关于Sort操作Sort合并、Sort常量上拉、SortProject下推等前面几篇文章都有讲解到,不熟悉的读者可以向前翻阅.