Hive优化器原理与源码解析系列--优化规则PartitionPruneRule(十四)
目录
背景
优化规则PartitionPruneRule
matches方法逻辑详解
onMatch方法逻辑详解
总结
背景
在HDFS存储形式如下:
transaction_detail/day=2019-11-11/file
transaction_detail/day=2019-11-12/file
transaction_detail/day=2019-11-13/file
......
同时,每张分区表的分区值,也会Hive元数据PARTITIONS中存有记录。PART_NAME列
当表数据量巨大时,读取全量数据就会成为一个瓶颈。那么创建分区是个不错的选择,可避免不必要地读取大量数据。当然要应用PartitionPruneRule优化规则,也是要满足匹配条件的,形如:
Filter
|
TableScan
的关系表达式树。
当遇到非此关系表达式树结构时,需要配合其他规则如谓词下推或其他能优化成Filter-TableScan的优化规则一起使用。
优化规则PartitionPruneRule
1)matches方法逻辑详解
matches方法返回此规则Rule是否可能与给定的操作数operands匹配,但是此方法的任何实现都可以给出误报,也就是说虽然规则与操作数匹配,但随后具OnMatch(ReloptRuleCall)而不生成任何后续任务。
判断由RelOptCall调用的优化规则Rule是否与输入参数RelNode关系表达式匹配,即此优化规则Rule能否应用到一个RelNode关系表达式树上。但此matches方法是继承自父类方法,默认返回true。
public boolean matches(RelOptRuleCall call) {
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)获取Filter操作和call.rel(1)获取TableScan操作,再调用perform方法识别并整理出分区字段列表。
@Override
public void onMatch(RelOptRuleCall call) {
HiveFilter filter = call.rel(0);//获取Filter操作
HiveTableScan tScan = call.rel(1);//获取TableScan
perform(call, filter, tScan);
}
perform方法能根据所读取的HiveTableScan表中Filter中谓词部分提取出哪些表中字段谓词判断,哪些是分区字段过滤条件,识别到分区字段限制条件后可直接定位到HDFS上目录存储的数据,如transaction_detail/day=2019-11-11/file。而不是读取全表数据后再去过滤谓词条件包括分区字段判断条件浪费大量不必要的IO。
protected void perform(RelOptRuleCall call, Filter filter,
HiveTableScan tScan) {
RelOptHiveTable hiveTable = (RelOptHiveTable) tScan.getTable();//获取所读取的表
RexNode predicate = filter.getCondition();//获取谓词条件的表达式
Pair<RexNode, RexNode> predicates = PartitionPrune
.extractPartitionPredicates(filter.getCluster(), hiveTable, predicate);//提取出谓词中分区字段
RexNode partColExpr = predicates.left;//predicates左侧为分区字段的表达式
hiveTable.computePartitionList(conf, partColExpr, tScan.getPartOrVirtualCols());
}
最后hiveTable.computePartitionList(conf, partColExpr, tScan.getPartOrVirtualCols())是识别分区列谓词条件的关键,先从HiveMeta元数据中判断是否是分区表,谓词中使用的是否的分区列等等判断后,才直接定位到数据在HDFS上目录下数据。
总结
对于熟悉Hive的童鞋,都知道Where条件后加分区列的限制条件,直接定位到HDFS上的存储目录下,但不知其中真正优化机制,是优化器做了列裁剪优化。
由于笔者知识及水平有限,因此文中错漏之处在所难免,恳请各位老师、专家不吝赐教。
往期文章分享
优化规则系列
Hive优化器原理与源码解析系列--优化规则SortRemoveRule(一)
Hive优化器原理与源码解析系列--优化规则SortJoinReduceRule(二)
Hive优化器原理与源码解析系列--优化规则SortProjectTransposeRule(三)
Hive优化器原理与源码解析系列--优化规则SortUnionReduceRule(四)
Hive优化器原理与源码解析系列--优化规则SortMergeRule(五)
Hive优化器原理与源码解析系列--优化规则ProjectFilterPullUpConstantsRule(六)
Hive优化器原理与源码解析系列--优化规则SortLimitPullUpConstantsRule(七)
Hive优化器原理与源码解析系列--优化规则UnionPullUpConstantsRule(八)
Hive优化器原理与源码解析系列--优化规则ProjectOverIntersectRemoveRule(九)
Hive优化器原理与源码解析系列--优化规则ProjectSortTransposeRule(十)
Hive优化器原理与源码解析系列--优化规则HiveProjectMergeRule(十一)
Hive优化器原理与源码解析系列--优化规则HiveJoinAddNotNullRule(十二)
Hive优化器原理与源码解析系列--优化规则HiveJoinCommuteRule(十三)
成本模型系列
Hive优化器原理与源码解析系列—统计信息带谓词选择率Selectivity
Hive优化器原理与源码解析系列--统计信息中间结果大小计算
Hive优化器原理与源码解析系列—CBO成本模型CostModel(一)
Hive优化器原理与源码解析系列—CBO成本模型CostModel(二)
Hive优化器原理与源码解析系列—统计信息UniqueKeys列集合
Hive优化器原理与源码解析—统计信息Parallelism并行度计算