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

【手写数据库核心揭秘系列】第74讲 物理计划操作符节点

开源无限 2025-04-01
42

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

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

一、概述 


物理执行计划是一个树形结构,它由一系列操作符节点组成,每个操作符对应一个具体的运算步骤。每一个操作符对应执行计划中的一个节点,它包括操作对应的方法,以及操作输入的数据。操作符的类型有扫描操作符,联接操作符,投影操作符,选择操作符等,当然还有其它一些操作,如排序去重、分组聚合等,这些待后面再实现。

二、操作函数 


每个操作符节点都应该包含一组统一的操作函数,也就是实现它的方法,每个操作的实现方法有多种,所以在此处以函数指针的方式来定义,在物理计划中根据实际情况采用对应的方法。

typedef struct PlanNode
{

    NodeType      type;
    ExecStateInfo *execInfo;
}PlanNode;

这一组操作函数在executor.h中定义如下,也是该操作实现的算法,目前含有三个接口:

  • execNodeProc,操作符执行主函数;
  • execNodeReProc,操作符重置函数,经过重置后可以重新开始;
  • execNodeEndProc,操作符执行结束函数,在此处可以进行资源释放等操作。
typedef struct ExecStateInfo
{

    execNodeProcFunc execNodeProc;
    execNodeProcFunc execNodeReProc;
    execNodeProcFunc execNodeEndProc;
}ExecStateInfo;

每个函数通过函数指针的定义,它们都有统一的入参和返回值。

typedef Node* (*execNodeProcFunc)(Node *planNode);

三、扫描操作 


查找一张数据表的数据,有多种具体的操作方式,比如:顺序扫描,顺序读取全部表数据;索引扫描,在索引中查找,快速定位数据位置。

扫描操作节点定义如下:

typedef struct ScanNode
{

    PlanNode    planInfo;
    Node        *tblRefInfoNode;
    ScanInfo    *scanInfo;
}ScanNode;

结构成员含义:

  • tblRefInfoNode,扫描的数据源表信息;
  • scanInfo,扫描相关信息,如扫描的起始位置等。

四、联接操作 


处理两张表的联接时,可以选择多种算法进行实现,比如:

  • 嵌套循环,类似于两层循环,外层遍历外表,内层遍历内表,在内循环中查找匹配项;
  • 哈希联接,将其中的小表的连接属性列构造哈希表,遍历大表数据,依次在哈希表中查找匹配项;
  • 归并连接,通过对两张数据表的连接属性列分别进行排序,然后通过合并来查找匹配项。

嵌套循环方式是最简单的一种,对于两个小规模的数据表来讲,它的效率是非常高的,这里先来实现它。

typedef struct NestLoopNode
{

    PlanNode        planInfo;
    JoinType        joinType;
    Node            *parserNode;
    Node            *leftplan;
    Node            *rightplan;
    Node            *joinExpr;
    Node            *lresult;
    Node            *rresult;
}NestLoopNode;

结构成员说明:

  • joinType, 联接类型;
  • parserNode,联接对应的解析树;
  • leftplan,联接执行节点的左子节点,也就是外层表;
  • rightplan,联接执行节点的右子节点,也就是内层表;
  • joinExpr,联接表达式执行子计划树;
  • lresult,外层表执行结果;
  • rresult,内层表执行结果;

五、投影操作 


投影操作是关系代数中的一个基本操作,也就是在结果集中选出目标列对应的那些列的值。

typedef struct ProjectNode
{

    PlanNode      planInfo;
    Node          *targetList;
    Node          *subNode;
}ProjectNode;

成员介绍:

  • targetList,目标属性列表;
  • subNode,子执行计划节点,由它返回结果集。

六、选择操作 


选择操作就是过滤掉不符合条件的数据行,它会将结果代入表达式进行计算。

typedef struct SelectNode
{

    PlanNode        planInfo;
    Node            *expr;
    Node            *subNode;
    Node            *resultList;    
}SelectNode;

成员介绍:

  • expr,表达式信息;
  • subNode,子执行计划节点,由它返回结果集;
  • resultList,记录结果集信息。

七、总结 


本节新增内容在exam_47目录下,在node.h中定义。

🌟 点赞收藏,分享给身边的技术伙伴,关注我们,持续获取数据库内核开发的硬核干货!一起从源码级实现到分布式架构,解锁数据库技术的每一个核心细节!🚀
【往期精彩推荐】

【手写数据库核心揭秘系列】第73讲 物理执行计划介绍

【手写数据库核心揭秘系列】第72讲 3步搞定多表查询列冲突:揭秘目标列检查的底层逻辑!

【手写数据库核心揭秘系列】第71讲 3步拆解 SELECT * 底层逻辑:揭秘目标列处理的代码级实现!


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

评论