暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【手写数据库核心揭秘系列】第76讲 普通表生成扫描节点,无条件下多表查询为何可能引发性能灾难?

开源无限 2025-04-03
28

💻 深耕数据库内核架构设计与开发十余年,曾主导多款高性能分布式数据库内核研发,攻克高并发、低延迟等核心技术难题。现倾力打造《从零手写数据库》系列教程,首次系统性公开数据库内核源码级实现细节!

🚀 从存储引擎、查询优化到分布式事务,手把手拆解核心模块;从语法解析树构建到执行计划生成,逐行代码还原设计精髓
🌟 无论你是数据库开发者、系统架构师,还是对底层技术充满好奇的极客,这里都有你想要的“硬核干货”!点击关注,与行业老兵共同探索数据库技术的星辰大海!

一、概述 


扫描节点作为计划树的叶子节点,每个数据源表都会对应一个扫描节点。

每个简单数据源表会转换为一个扫描操作符节点,当为单个数据源表时,下层只有一个扫描操作符节点。

当有多个数据源表并列时,数据源表之间是不带条件的联接关系,将数据源转换为扫描节点的同时,需要增加上层的联接节点。

二、数据源处理接口 


为了可以递归重用,这里增加了一个分发函数,可以按数据源或操作符的类型调用对应的处理函数,方便递归调用。

Node* TablePlanNode(Node *node)
{
    Node *subplan = NULL;

    switch (node->type)
    {
    case T_TableRefInfo:
        subplan = ScanPlanNode((TableRefInfo*)node);
        break;
    case T_JoinTblInfo:
        subplan = JoinPlanNode((JoinTblInfo *)node);
        break;
    case T_NestLoopNode:
        subplan = node;
        break;
    default:
        break;
    }

    return subplan;
}

本节介绍普通数据源的处理,联合数据源表下节继续介绍。

三、单个数据源表 


扫描节点的生成,初始化对应的扫描数据表信息和操作符算法接口,并将该数据源表标记为已经在执行计划中。

Node* ScanPlanNode(TableRefInfo *tblRefInfoNode)
{
    ScanNode *scanNode = (ScanNode*)NewNode(ScanNode);
    scanNode->tblRefInfoNode = (Node*)tblRefInfoNode;
    scanNode->planInfo.execInfo = &seqScanStateInfo;

    tblRefInfoNode->isPlan = 1;    
    return (Node*)scanNode;
}

四、多个数据源表 


当有多个数据源表时,前两个数据源表会增加一个表联接操作节点,扫描节点作为它的左右子节点。

第三张数据源表与联接数据源再进行嵌套联接,新增一个表联接操作节点,而扫描节点作为右子树,也就是内表,原联接操作节点作为左子树。

Node* CrossJoinPlan(Node *subplan, Node *node)
{
    NestLoopNode *nlNode = NULL;

    if(subplan == NULL)
    {
        subplan = TablePlanNode(node);
    }
    else
    {
        nlNode = NewNode(NestLoopNode);
        nlNode->joinType = JOIN_CROSS;
        nlNode->parserNode = NULL;

        nlNode->leftplan = subplan;
        nlNode->rightplan = TablePlanNode(node);
        nlNode->planInfo.execInfo = &nestloopStateInfo;
        nlNode->lresult = NULL;
        nlNode->rresult = NULL;

        subplan = (Node*)nlNode;
    }

return subplan;
}

当from子句中有多个数据表时,它们就会构成嵌套级联的联接关系,用嵌套循环算法实现时,就会有多层循环。

五、总结 


本节新增内容在exam_47目录下,在执行计划模块plan的plan.c中定义。

🌟 点赞收藏,分享给身边的技术伙伴,关注我们,持续获取数据库内核开发的硬核干货!一起从源码级实现到分布式架构,解锁数据库技术的每一个核心细节!🚀
【往期精彩推荐】
【手写数据库核心揭秘系列】第75讲 查询执行计划树的生成,执行计划树的生成逻辑,手把手拆解
【手写数据库核心揭秘系列】第74讲 物理计划操作符节点
【手写数据库核心揭秘系列】第73讲 物理执行计划介绍


文章转载自开源无限,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论