一、概述
在物理执行计划生成阶段,首先处理联接数据源,在逻辑执行计划阶段已经将每个联接数据源都添加到了列表当中, 当然对于嵌套联接的情况,子联接数据源也会被添加到列表当中。
在物理计划中,对于联接子句的处理主要有以下内容:
将联接数据源转换为嵌套循环执行节点;因为当前联接只实现了一种执行算子,不同联接类型都使用这一种算法。 递归调用联接数据源处理函数,将嵌套联接数据源的子节点联接数据源也转换为嵌套循环执行节点;其实嵌套联接数据源会被转换为一棵二叉子树,它根节点和分支节点都会嵌套循环节点,叶子节点为目标列或者常量节点。 将上述转换后的联接执行子树添加到一个列表当中; 因为可能会存在多个子树的情况,当联接数据源子树多于一个时,将它们之间采用笛卡尔积的方式联接起来。
二、联接数据源处理
联接执行节点处理和生成函数为:
ounter(lineNode *JoinPlanProcess(QueryStmt *queryStmt)
将逻辑执行计划阶段生成的联接数据源,转换为联接执行节点,并将它们加到列表当中。
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linefor(listNode = ((List*)queryStmt->joinList)->head; listNode != NULL; listNode = listNode->next){JoinTblInfo* joinTbl = (JoinTblInfo*)listNode->value;if(joinTbl->isPlan)continue;node = TablePlanNode((Node*)joinTbl);if(node != NULL)list = (List*)AppendList(list, node);}
每遇到一个联接数据源,都会中序遍历递归处理它的左右子节点,
在这个递归过程中,联接数据源列表中部分联接数据已经被处理,所以在遍历时,需要判断是否已经在执行计划当中,只有没在计划当中时再会被单独处理。
三、生成联接执行节点
将联接数据源转换为联接执行节点,并将节点各成员初始化,然后递归处理它的左右子节点,直到叶子节点。
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineNode* JoinPlanNode(JoinTblInfo *joinTbl){NestLoopNode *nlNode = (NestLoopNode*)NewNode(NestLoopNode);nlNode->joinType = joinTbl->joinType;nlNode->parserNode = (Node*)joinTbl;nlNode->planInfo.execInfo = &nestloopStateInfo;nlNode->joinExpr = joinTbl->joinExpr;nlNode->lresult = NULL;nlNode->rresult = NULL;nlNode->needOuter = 1;joinTbl->isPlan = 1;if(joinTbl->leftTblInfo != NULL){nlNode->leftplan = TablePlanNode(joinTbl->leftTblInfo);}if(joinTbl->rightTblInfo != NULL){nlNode->rightplan = TablePlanNode(joinTbl->rightTblInfo);}return (Node*)nlNode;}
成员赋值:
joinExpr,联接表达式; execInfo,联接执行算子;目前用嵌套循环方式实现; needOuter,联接执行参数,开始时先从外表开始扫描; isPlan,添加到执行计划标志。
四、生成联接执行计划树
最后将所有联接执行节点串联成树,独立的联接执行节点间通过无条件的内联接组织成一棵二叉树。
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineif((list != NULL) && (list->length > 1)){subplan = node;for(listNode = list->head; listNode != NULL; listNode = listNode->next){if(listNode->value == node)continue;subplan = CrossJoinPlan(subplan, listNode->value);}}else{if(list != NULL)subplan = list->head->value;}
五、总结
本节内容主要实现联接表达式物理执行计划中的改变,实现位于exam_52目录下的plan.c文件中。
🌟 点赞收藏,分享给身边的技术伙伴,关注我们,持续获取数据库内核开发的硬核干货!一起从源码级实现到分布式架构,解锁数据库技术的每一个核心细节!🚀【手写数据库核心揭秘系列】第95讲 联合查询,联接表达式的执行计划生成
文章转载自开源无限,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




