• Calcite分析 -- SortRemoveRule


    Calcite Version:1.26.0

    Rule执行之前的情况,

    对#19,apply SortRemoveRule

    #19的input是rel#13:RelSubset#2.NONE.[]

    这里就是将Sort中的,collation,放到RelSubset#2.NONE.[]的input上去,从而后续可以move掉这个sort

    这里的逻辑看,只要是不带offset和fetch的sort,都会remove掉

    完整的过程是,logicalSort with limit,通过EnumerableRule,生成一个新的sort算子和Limit算子;然后再用SortRemoveRule,将这个生成的sort remove掉。

    convet的结果,就生成一个带collation的subset,

    然后再用,rel#23:RelSubset#2.NONE.[0 DESC-nulls-last]调用transformTo

    在ensureRegistered中,有RelSet的Merge

    equivRel,是触发这个rule的算子,

    这里触发merge的条件,是传入的rel和equiRel的subset都存在,并且他们的relset还不同

    tranform这里的逻辑,一般两种,

    convert,生成新的Relnode,transform,这种情况下传入的RelNode是还未注册的,不需要merge

    convert,transform,这种情况下传入的就是Subset,但是一般Rule都是把当前Relset中的node做转换,所以也不需要merge

    这里的情况,Convert的参数是sort.getInput,所以转换的别的RelSet中的Subset,这就需要merge

    Merge

    Merge With

    先remove

    复制subset

    其实就是在新的RelSet中,重新创建相应的traitSet的subset,这里需要区分required参数

    复制RelNode

     reregister,主要是调用addReltoSet

     结果,

    其他的处理,

    对于parent,需要调用fixInput,然后重新算digest,

    最后对于,merge完的RelNode和Subset,做一下firerules,

    ruleDriver.onSetMerged(set)

    如果一个RelSet merge了其他的RelSet,

    那么需要把他下面的subset,以及所有ancestor的subset的Optimize状态给clear掉,这样可以重新优化一遍

    同时这个RelSet的exploringState也会被设置成null

    ancestor的意思是parent,当前的优化变动只会影响到后续优化,但在已优化的子集不会影响

    看下clear之前的状态,

    首先Clear的Relset@5532

    parent对应的RelSet是,5577,情况和5532正好相反,

    Subset都在优化中,但是RelSet的exploringState为null,

    RelSubset.taskState和RelSet.exploringState,代表什么?

    taskState,两种状态,

    /** State of optimizer. */
    enum OptimizeState {
    OPTIMIZING,
    COMPLETED
    }

    分别在OptimizeGroup Task和GroupOptimized Task中被设置

    exploringState,也是两种状态,

    /**
    * An enum representing exploring state of current RelSet.
    */
    enum ExploringState {
    /**
    * The RelSet is exploring.
    * It means all possible rule matches are scheduled, but not fully applied.
    * This RelSet will refuse to explore again, but cannot provide a valid LB.
    */
    EXPLORING,

    /**
    * The RelSet is fully explored and is able to provide a valid LB.
    */
    EXPLORED
    }

    在ExploreInput Task中会设置成Exploring,在EnsureGroupExplored中设置成Explored

    不是Explored,可以触发OptimizeMExpr Task;是Null可以触发ExploreInput Task

    再看回前面的逻辑,

    首先会把两个state都清空了,那么意味着对于这个Subset,可以继续调度OptimizeMExpr或OptimizeGroup

    只要两个任意一个原先不为null,就需要继续clear parent

    所以最终结果是,两个RelSet的相应flag都被清掉

    这里最后,当遍历到rel#16:RelSubset#3.ENUMERABLE.[0 DESC-nulls-last],这个是root,按逻辑所以触发生成OptimizeGroup

    why?

    对于其他的RelSet,把taskState设置掉,就会有机会被重新优化,但对于root,你必须显式的触发OptimizeGroup,否则没机会被再次优化

  • 相关阅读:
    自己定义button
    Google C++ style guide——格式
    杭电1018-Big Number(大数)
    AnyForWeb告诉你什么才是“最好的”编程语言
    Android广播机制分析
    nyoj Wythoff Game(暴力枚举)
    基础搜索入门(二)
    1.1、Libgdx目标和特性
    我在农业2.0的互联网创业思考 (1)
    Python演绎的精彩故事(二)
  • 原文地址:https://www.cnblogs.com/fxjwind/p/15220576.html
Copyright © 2020-2023  润新知