热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

openGauss数据库源码解析系列文章——执行器解析(三)

本篇介绍执行器解析中“向量化

在上一篇openGauss数据库源码解析系列文章——执行器解析(二)中,介绍了执行器解析中“7.4 表达式计算”及“7.5 编译执行”的相关内容,本篇将介绍“7.6 向量化引擎”的精彩内容。完整版内容请查看CSDN·Gauss松鼠会专栏博客,以下内容为章节试读:

7.6  向量化引擎

传统的行执行引擎大多采用一次一元组的执行模式,这样在执行过程中CPU大部分时间并没有用来处理数据,更多的是在遍历执行树,就会导致CPU的有效利用率较低。而在面对OLAP场景巨量的函数调用次数,需要巨大的开销。为了解决这一问题,openGauss中增加了向量化引擎。向量化引擎使用了一次一批元组的执行模式,能够大大减少遍历执行节点的开销。一次一批元组的数据运载方式也为某些表达式计算的SIMD(single instruction, multiple data,单指令多数据)化提供了机会,SIMD化能够带来性能上的提升。同时向量化引擎还天然对接列存储,能够较为方便地在底层扫描节点装填向量化的列数据。

向量化引擎的执行算子类似于行执行引擎,包含控制算子、扫描算子、物化算子和连接算子。同样会使用节点表示,继承于行执行节点,执行流程采用递归方式。主要包含的节点有:CStoreScan(顺序扫描),CStoreIndexScan(索引扫描),CStoreIndexHeapScan(利用Bitmap获取元组),VecMaterial(物化),VecSort(排序),VecHashJoin(向量化哈希连接)等,下面将逐一介绍这些执行算子。

7.6.1  控制算子

1. VecResult算子

VecResult算子用于处理只有一个结果返回或WHERE过滤条件为常量的情况,对应的代码源文件是“vecresult.cpp”;对应的主要数据结构是VecResult,VecResult继承于BaseResult。VecResult算子相关的函数包括ExecInitVecResult(初始化节点)、ExecVecResult(执行节点)、ExecReScanVecResult(重置节点)、ExecEndVecResult(退出节点)。

ExecInitVecResult函数用于初始化VecResult执行算子。执行流程如图一所示,主要执行流程如下。

(1) 创建并初始化VecResult执行节点,并为节点创建表达式上下文。
(2) 调用“ExecInitResultTupleSlot(estate, &res_state->ps)”函数分配存储投影结果的slot。
(3) 调用投影表达式初始化函数ExecInitVecExpr依次对ps.targetlist、ps.qual和resconstantqual进行初始化。
(4) 分别调用ExecAssignResultTypeFromTL函数和ExecAssignVectorForExprEval函数进行扫描描述符的初始化和投影结构的创建。

图一  ExecInitVecResult函数执行流程

ExecVecResult函数是执行VecResult的主体函数。执行流程如图二所示,主要执行流程如下。

(1) 检查是否需要计算常量表达式。
(2) 若需要则重新计算表达式,设置检查标识(如果常量计算表达式结果为false时,则设置约束检查标识位)。
(3) 获取结果元组。

图二 ExecVecResult函数执行流程

ExecReScanVecResult函数用于重新执行扫描计划。

ExecEndVecResult函数用于在执行结束时释放执行过程中申请的相关资源(包括存储空间等)。

2. VectorModifyTable算子

VecModifyTable算子用于处理INSERT、UPDATE、DELETE操作,对应的代码源文件是“vecmodifytable.cpp”;对应的主要数据结构是VecModifyTableState,VecModifyTableState继承于ModifyTableState。具体定义代码如下所示:

    typedef struct VecModifyTableState : public ModifyTableState {
    VectorBatch* m_pScanBatch; /* 工作元组 */
    VectorBatch* m_pCurrentBatch; /* 输出元组 */
    } VecModifyTableState;

    VecModifyTable算子相关的函数包括ExecInitVecModifyTable(初始化节点)、ExecVecModifyTable(执行节点)、ExecEndVecModifyTable(退出节点)。

    ExecInitVecModifyTable函数用于初始化VecModifyTable算子,调用ExecInitModifyTable函数实现算子的初始化。

    ExecVecModifyTable函数是执行VecModifyTable算子的主体函数,循环地从子计划中获取目标列并根据要求修改每一列,通过“switch(operation)”处理不同的修改操作,具体的修改操作包括CMD_INSERT(插入)、CMD_DELETE(删除)、CMD_UPDATE(更新)。

    ExecEndVecModifyTable函数用于在执行VecModifyTable算子结束时调用ExecEndModifyTable函数清除相关资源。

    3. VecAppend算子

    VecAppend算子用于处理包含一个或多个子计划的链表,通过遍历子计划链表逐个执行子计划,对应的代码源文件是“vecappend.cpp”;对应的主要数据结构是VecAppendState,VecAppendState继承于AppendState。

    VecAppend算子相关的函数包括ExecInitVecAppend(初始化节点)、ExecVecAppend(执行节点)、ExecReScanAppend(重置节点)、ExecEndVecAppend(退出节点)。

    ExecInitVecAppend函数用于初始化VecAppend算子。执行执行流程如图三所示,主要执行流程如下。

    (1) 创建并初始化执行节点VecAppend。
    (2) 分配存储投影结果的slot。
    (3) 循环初始化子计划链表。
    (4) 初始化扫描描述符并设置初始迭代。

    图三  ExecInitVecAppend函数执行流程

    ExecVecAppend函数是执行VecAppend算子的主体函数。执行流程如图四所示,每次从子计划中获取一条元组,当取回全部元组时,移动到下一个子计划,直到执行全部子计划。

    图四  ExecVecAppend执行流程

    ExecEndVecAppend函数用于在执行结束时清理VecAppend算子,释放相应的子计划。

    7.6.2  扫描算子

    1. CStoreScan算子

    CStoreScan算子用于扫描基础表,按顺序扫描基础表,对应的代码源文件是“veccstore.cpp”;CStoreScan算子对应的主要数据结构是CStoreScanState,CStoreScanState继承于ScanState。具体定义代码如下:

      typedef struct CStoreScanState : ScanState {
      Relation ss_currentDeltaRelation;
      Relation ss_partition_parent;
      TableScanDesc ss_currentDeltaScanDesc;
      bool ss_deltaScan;
      bool ss_deltaScanEnd;
      VectorBatch* m_pScanBatch;
      VectorBatch* m_pCurrentBatch;
      CStoreScanRunTimeKeyInfo* m_pScanRunTimeKeys;
      int m_ScanRunTimeKeysNum;
      bool m_ScanRunTimeKeysReady;
      CStore* m_CStore;
      CStoreScanKey csss_ScanKeys;
      int csss_NumScanKeys;
      bool m_fSimpleMap;
      bool m_fUseColumnRef;
      vecqual_func jitted_vecqual;
      bool m_isReplicaTable; *复制表标记符*/
      } CStoreScanState;

      CStoreScan算子的相关函数包括:ExecInitCStoreScan(初始化节点)、ExecCStoreScan(执行节点)、ExecEndCStoreScan(退出节点)、ExecReScanCStoreScan(重置节点)。

      ExecInitCStoreScan函数用于初始化CStoreScan算子。主要执行流程如下。

      (1) 创建并初始化CStoreScan算子,为节点创建表达式上下文。
      (2) 调用ExecAssignVectorForExprEval函数进行投影表达式的初始化。
      (3) 调用ExecInitResultTupleSlot函数和ExecInitScanTupleSlot函数分别初始化用于投影结果和用于扫描的slot。
      (4) 打开扫描表,调用ExecAssignResultTypeFromTL函数和ExecBuildVecProjectionInfo函数分别初始化结果扫描描述符和创建投影结构。

      ……(本节内容未完)


      完整版内容,请点击“阅读原文”



      推荐阅读
      • 入门指南:使用FastRPC技术连接Qualcomm Hexagon DSP
        本文旨在为初学者提供关于如何使用FastRPC技术连接Qualcomm Hexagon DSP的基础知识。FastRPC技术允许开发者在本地客户端实现远程调用,从而简化Hexagon DSP的开发和调试过程。 ... [详细]
      • 视觉Transformer综述
        本文综述了视觉Transformer在计算机视觉领域的应用,从原始Transformer出发,详细介绍了其在图像分类、目标检测和图像分割等任务中的最新进展。文章不仅涵盖了基础的Transformer架构,还深入探讨了各类增强版Transformer模型的设计思路和技术细节。 ... [详细]
      • 网络流24题——试题库问题
        题目描述:假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算 ... [详细]
      • td{border:1pxsolid#808080;}参考:和FMX相关的类(表)TFmxObjectIFreeNotification ... [详细]
      • 本文详细介绍了Oracle 11g中的创建表空间的方法,以及如何设置客户端和服务端的基本配置,包括用户管理、环境变量配置等。 ... [详细]
      • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
      • 洛谷 P4009 汽车加油行驶问题 解析
        探讨了经典算法题目——汽车加油行驶问题,通过网络流和费用流的视角,深入解析了该问题的解决方案。本文将详细阐述如何利用最短路径算法解决这一问题,并提供详细的代码实现。 ... [详细]
      • 本文深入探讨了Go语言中的接口型函数,通过实例分析其灵活性和强大功能,帮助开发者更好地理解和运用这一特性。 ... [详细]
      • spring boot使用jetty无法启动 ... [详细]
      • Windows操作系统提供了Encrypting File System (EFS)作为内置的数据加密工具,特别适用于对NTFS分区上的文件和文件夹进行加密处理。本文将详细介绍如何使用EFS加密文件夹,以及加密过程中的注意事项。 ... [详细]
      • linux网络子系统分析(二)—— 协议栈分层框架的建立
        目录一、综述二、INET的初始化2.1INET接口注册2.2抽象实体的建立2.3代码细节分析2.3.1socket参数三、其他协议3.1PF_PACKET3.2P ... [详细]
      • 本文详细探讨了在Web开发中常见的UTF-8编码问题及其解决方案,包括HTML页面、PHP脚本、MySQL数据库以及JavaScript和Flash应用中的乱码问题。 ... [详细]
      • 本文详细介绍了如何在循环双链表的指定位置插入新元素的方法,包括必要的步骤和代码示例。 ... [详细]
      • 如何高效解决Android应用ANR问题?
        本文介绍了ANR(应用程序无响应)的基本概念、常见原因及其解决方案,并提供了实用的工具和技巧帮助开发者快速定位和解决ANR问题,提高应用的用户体验。 ... [详细]
      • SQL Server 存储过程实践任务(第二部分)
        本文档详细介绍了三个SQL Server存储过程的创建与使用方法,包括统计特定类型客房的入住人数、根据房间号查询客房详情以及删除特定类型的客房记录。 ... [详细]
      author-avatar
      圈闭仔笨仔
      这个家伙很懒,什么也没留下!
      PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
      Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有