目录
背景
优化规则HiveFilterAggregateTransposeRule
总结
背景
这篇文章来讲优化规则HiveFilterAggregateTransposeRule,主要功能是将Filter过滤器下推到Aggregate聚合操作之下。满足的前提条件,这些谓词表达式必须是确定性的。
谓词下推,优化的思路大致为尽量地将过滤条件下推到离数据源近的位置。提前过滤掉减少数据量,减少不必要的IO。记录数和IO同时都是HiveCostModel成本模型的关键构成指标。但前提必须满足等价变换的大前提,所谓等价变换,就是相同的输入,返回相同的确定的结果,优化就是减少或降低中间过程的计算成本。
Fileter过滤器操作和Aggregate聚合操作调换顺序,也是谓词下推一种的优化规则。
优化规则HiveFilterAggregateTransposeRule
1)matches方法逻辑详解
matches方法返回此规则Rule是否可能与给定的操作数operands匹配,但是此方法的任何实现都可以给出误报,也就是说虽然规则与操作数匹配,但随后具OnMatch(ReloptRuleCall)而不生成任何后续任务。
判断由RelOptCall调用的优化规则Rule是否与输入参数RelNode关系表达式匹配,即此优化规则Rule能否应用到一个RelNode关系表达式树上。
这里Hive实现了自己的判断,要求Filter操作的谓词条件,必须是确定性谓词表达式,否则退出优化。
表达式的确定性与非确定性区别:
一个表达式确定性与非确定性的区别是给定函数同一个确定值,是否永远返回同一个确定值。刚好相反的是非确定性函数,如随机函数Randow()每次返回的值都不确定。
关于onMatch方法优化规则HiveFilterAggregateTransposeRule没有实现,而是直接继承了Calcite实现优化规则父类FilterAggregateTransposeRule。
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优化规则的调用。
首先分别获取Filter和Aggregate对象,使用RelOptUtil.conjunctions把Filter对象谓词条件分解成有AND连接行表达式列表。获取Aggregate对象引用的字段列表,并判断与getGroupSet索引字段引用调整因子,以备下推Filter后AGG字段引用的调整使用。
分离出哪些为可下推的谓词及其余不能下推的谓词列表。
首先conditions谓词列表,InputFinder访问遍历器生成表达式所用输入的位图,并使用bits返回描述表达式RelNode使用的输入的位集。canPush判断当前AGG对象中的,此谓词表达式元素是否可下推(canPush方法文章后面有讲解)。使用RelOptUtil.RexInputConverter遍历表达式树,根据调整因子adjustments转换RexInputRefs的索引并添加到可下推pushedConditions列表中,否则其余的谓词存放remainingConditions列表中。
接下来,生成RelBuilder构建器对象,把谓词下推到AGG的子输入INPUT压入构建器,如果刚压入的带有下推谓词表达式的INPUT和原AGG的输入相同,则没有优化的必要,退出优化。复制AGG特征集合并使用已下推谓词的子输入RelNode生成新的RelNode对象,再补上剩余的没有下推的谓词条件,注册到RelSet等价关系表达式集合,以备优化器成本评估和选择,构建出最优的执行计划。
3)canPush判断谓词表达式是否能下推的方法
如果Filter所引用的字段,没在GroupBy中使用,则不能下推。还有如果使用GroupSet语句,并在谓词表达式中出现的字段引用,都在grouping sets中出现,也是可以下推的。
总结