ORCA优化器浅析——CJobGroupExpressionExploration探究

ORCA优化器浅析——CJobGroupExpressionExploration探究CJobGroupExpressionExploration类作为Exploregroupexpressionoptimizationjob,主要负责创建给定组表达式的逻辑重写

CJobGroupExpressionExploration类作为Explore group expression optimization job,主要负责创建给定组表达式的逻辑重写。请注意,组探索作业需要为基础组中的每个组表达式运行组表达式探索作业(Responsible for creating the logical rewrites of a given group expression. Note that a group exploration job entails running a group expression exploration job for each group expression in the underlying group)。
在这里插入图片描述
首先介绍一点:如图每个 Group【代码中体现为CGroup】 保存的是逻辑等价的GroupExpression【代码中体现为CGroupExpression】;而GroupExpression作为表达式在Cascades中的管理器,真正的优化单元。这里的CJobGroupExpressionExploration就是用于执行GroupExpression Exploration(主要负责推导等价的逻辑表达式)的任务单元。CJobGroupExpressionExploration继承自CJobGroupExpression,而CJobGroupExpression继承自CJob类。

状态流图

CJobGroupExpression使用JSM实现了逻辑状态机,其状态流转如下图所示。由void CJobGroupExpressionExploration::Init(CGroupExpression *pgexpr)函数对CJobGroupExpression实例进行初始化,首先调用父类CJobGroupExpression::Init(pgexpr)函数,其实就是设置父类中的m_pgexpr = pgexpr,以及m_fChildrenScheduled和m_fXformsScheduled为true;调用m_jsm.Init函数初始化逻辑状态机,然后会设置状态机每个状态下执行的函数,如下所示:

 // set job actions m_jsm.SetAction(estInitialized, EevtExploreChildren); m_jsm.SetAction(estChildrenExplored, EevtExploreSelf); m_jsm.SetAction(estSelfExplored, EevtFinalize); 

在这里插入图片描述
在这里插入图片描述

ScheduleJob

首先介绍ScheduleJob,该函数是创建调度CJobGroupExpression任务的API(Schedule a new group expression exploration job)。该函数通过JobFactory的PjCreate函数创建CJob::EjtGroupExpressionExploration类型任务,也就是CJobGroupExpression任务,调用Init函数进行初始化,最后通过CScheduler的Add函数建立新建的任务与当前类任务实例的父子关系,并加入到任务等待队列waiting list中。

void CJobGroupExpressionExploration::ScheduleJob(CSchedulerContext *psc, CGroupExpression *pgexpr, CJob *pjParent){ 
    CJob *pj = psc->Pjf()->PjCreate(CJob::EjtGroupExpressionExploration); // initialize job CJobGroupExpressionExploration *pjege = PjConvert(pj); pjege->Init(pgexpr); psc->Psched()->Add(pjege, pjParent); } 

EevtExploreChildren

首先看在estInitialized状态下,调用的函数EevtExploreChildren。该函数首先看父类CJobGroupExpression的m_fChildrenScheduled是否为true,如果为true说明已经调度过子任务,可以转移到下一个状态;否则,将CGroupExpression m_pgexpr状态设置为CGroupExpression::estExploring,说明正在Exploring,调用ScheduleChildGroupsJobs函数。

CJobGroupExpressionExploration::EEvent CJobGroupExpressionExploration::EevtExploreChildren(CSchedulerContext *psc, CJob *pjOwner) { 
    CJobGroupExpressionExploration *pjgee = PjConvert(pjOwner); // get a job pointer if (!pjgee->FChildrenScheduled()) // m_fChildrenScheduled { 
    pjgee->m_pgexpr->SetState(CGroupExpression::estExploring); pjgee->ScheduleChildGroupsJobs(psc); return eevExploringChildren; }else{ 
    return eevChildrenExplored; } } 

ScheduleChildGroupsJobs函数的作用时为所有子groups都调度exploration任务。注意这里的 m_pgexpr->Arity()代表该表达式关联的子group的数量,而[]号也被CGroupExpression重载过。详细细节可以看CGroupExpression实现。

void CJobGroupExpressionExploration::ScheduleChildGroupsJobs(CSchedulerContext *psc) { 
    ULONG arity = m_pgexpr->Arity(); for (ULONG i = 0; i < arity; i++) CJobGroupExploration::ScheduleJob(psc, (*(m_pgexpr))[i], this); SetChildrenScheduled(); } 

从开头的图中我们看到,Group0中的Selection,Join是等价的Group Expression,作为Group0的子Group Expression。因此,每个Group Expression又引用了其他的Group,作为这个表达式的子Group。所以这里的ScheduleChildGroupsJobs会为Group Expression的子groups都调度起CJobGroupExploration任务。

EevtExploreSelf

当子group都Explored之后,进入了estChildrenExplored状态,状态机开始调用EevtExploreSelf函数。首先查看父类的m_fXformsScheduled Xform是否已经应用过了,如果是,进入下一个状态eevSelfExplored;否则需要调用ScheduleApplicableTransformations函数。

CJobGroupExpressionExploration::EEvent CJobGroupExpressionExploration::EevtExploreSelf(CSchedulerContext *psc, CJob *pjOwner){ 
    CJobGroupExpressionExploration *pjgee = PjConvert(pjOwner); // get a job pointer if (!pjgee->FXformsScheduled()) { 
    // m_fXformsScheduled pjgee->ScheduleApplicableTransformations(psc); return eevExploringSelf; }else{ 
    return eevSelfExplored; } } 

ScheduleApplicableTransformations函数首先从m_pgexpr中获取到CLogical操作符的规则集,然后拿操作符的规则集和逻辑变换集合取与,得到操作符Exploration阶段需要的规则,然后通过父类的ScheduleTransformations函数使用每个规则对m_pgexpr进行转换

//--------------------------------------------------------------------------- // @function: // CJobGroupExpressionExploration::ScheduleApplicableTransformations // @doc: // Schedule transformation jobs for all applicable xforms //--------------------------------------------------------------------------- void CJobGroupExpressionExploration::ScheduleApplicableTransformations( CSchedulerContext *psc) { 
    // get all applicable xforms COperator *pop = m_pgexpr->Pop(); CXformSet *xform_set = CLogical::PopConvert(pop)->PxfsCandidates(psc->GetGlobalMemoryPool()); // intersect them with required xforms and schedule jobs xform_set->Intersection(CXformFactory::Pxff()->PxfsExploration()); xform_set->Intersection(psc->Peng()->PxfsCurrentStage()); ScheduleTransformations(psc, xform_set); xform_set->Release(); SetXformsScheduled(); } void CJobGroupExpression::ScheduleTransformations(CSchedulerContext *psc, CXformSet *xform_set){ 
    // iterate on xforms CXformSetIter xsi(*(xform_set)); while (xsi.Advance()){ 
    CXform *pxform = CXformFactory::Pxff()->Pxf(xsi.TBit()); CJobTransformation::ScheduleJob(psc, m_pgexpr, pxform, this); } } 

一个表达式,可能对应多个规则。Cascades的设计中,使用集合来管理规则。工程实现中,GPORCA使用位图来管理规则。规则的集合分两类:Exploration Set 用于Exploration的规则;Implementation Set 用于Implementation的规则。
每个操作符,都存有自己需要的规则ID构成的规则的子集,这里面包括了逻辑变换和实现变换的规则。

  • Exploration阶段,拿操作符的规则集和逻辑变换集合取与,得到操作符这个阶段需要的规则
  • Implementation阶段,拿操作符的规则集和实现变换集合取与,得到操作符这个阶段需要的规则集
    在这里插入图片描述
    GPORCA通过规则工程管理规则集,包括Exploration和Implementation。上图中,0和1有8列,表示规则集。为了简单,我们假设CLogicalGet需要的规则ID是4。LogicalGet所在的行,左边的规则集记录了LogicalGet需要的规则。可以看到第四位被设置为1,可以知道LogicalGet需要ID为4的规则进行转换。Exploration所在的行的规则集,表示所有的规则的集合。5,6,7,8位被设置为1,所以Exploration的规则集是ID为{5,6,7,8}的规则集。同样的,Implementation的规则集为{1,2,3,4}

规则匹配:Exploration优化阶段,LogicalGet和Exploration的规则集取与的结果为空集,所以直接跳过;Implementation阶段,取与的结果是4,是CXformGet2TableScan的ID,所以应用这个规则

EevtFinalize

在EevtFinalize状态下执行的函数EevtFinalize很简单,仅仅是将m_pgexpr状态改为了CGroupExpression::estExplored

CJobGroupExpressionExploration::EEvent CJobGroupExpressionExploration::EevtFinalize(CSchedulerContext *, CJob *pjOwner){ 
    CJobGroupExpressionExploration *pjgee = PjConvert(pjOwner); // get a job pointer pjgee->m_pgexpr->SetState(CGroupExpression::estExplored); return eevFinalized; } 

CJobGroupExpression类

CJobGroupExpression类作为Abstract superclass of all group expression optimization jobs,主要包含3个成员变量,即BOOL m_fChildrenScheduledBOOL m_fXformsScheduledCGroupExpression *m_pgexpr。CJobGroupExpression类实际就实现了如下两个函数,其中最重要的是ScheduleTransformations函数,该函数会遍历形参xform_set中的ExformId,并通过CXformFactory获取对应的CXform,最终使用CJobTransformation::ScheduleJob函数创建新Transformation任务。

//--------------------------------------------------------------------------- // @function: // CJobGroupExpression::Init // @doc: // Initialize job //--------------------------------------------------------------------------- void CJobGroupExpression::Init(CGroupExpression *pgexpr) { 
    m_fChildrenScheduled = false; m_fXformsScheduled = false; m_pgexpr = pgexpr; } //--------------------------------------------------------------------------- // @function: // CJobGroupExpression::ScheduleTransformations // @doc: // Schedule transformation jobs for the given set of xforms //--------------------------------------------------------------------------- void CJobGroupExpression::ScheduleTransformations(CSchedulerContext *psc, CXformSet *xform_set){ 
    // iterate on xforms CXformSetIter xsi(*(xform_set)); while (xsi.Advance()){ 
    CXform *pxform = CXformFactory::Pxff()->Pxf(xsi.TBit()); CJobTransformation::ScheduleJob(psc, m_pgexpr, pxform, this); } } 

Exploration(主要负责推导等价的逻辑表达式)和Implementation(主要负责把逻辑表达式转化为物理表达式)都是把一个表达式,转换为另一个等价的表达式,统称为Transformation;转换是基于规则进行的,称为基于规则的优化(Role Based Optimization,RBO)。因此CJobGroupExpressionExploration和CJobGroupExpressionImplementation类都会生成CJobTransformation任务。
在这里插入图片描述
在这里插入图片描述

今天的文章
ORCA优化器浅析——CJobGroupExpressionExploration探究分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/80119.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注