openGauss源码解析(117)

openGauss源码解析:执行器解析(10)

2. IndexScan算子

IndexScan算子是索引索引扫描算子,对应IndexScan计划节点,相关的代码源文件是“nodeIndexScan.cpp”文件。如果过滤条件涉及索引,查询计划对表的扫描使用IndexScan算子,利用索引加速元组获取。算子对应的主要函数如表7-13所示。

表7-13 IndexScan算子主要函数

主要函数

说明

ExecInitIndexScan

初始化IndexScan状态节点

ExecIndexScan

迭代获取元组

ExecEndIndexScan

清理IndexScan状态节点

ExecIndexMarkPos

标记扫描位置

ExecIndexRestrPos

重置扫描位置

ExecReScanIndexScan

重置IndexScan

ExecInitIndexScan函数负责初始化IndexScan状态节点。主要执行流程如下。

(1) 创建IndexScanState节点。
(2) 初始化子节点,初始化目标列表、索引过滤条件、原始过滤条件。
(3) 打开对应表。
(4) 打开索引。
(5) 构建索引扫描Key。
(6) 处理ORDER BY对应的Key。
(7) 启动索引扫描(返回索引扫描描述符IndexScanDesc)。
(8) 把过滤Key传递给索引器。

ExecIndexScan函数负责迭代获取元组,通过回调函数的形式调用IndexNext函数获取元组。IndexNext函数首先按照扫描Key获取元组,然后再执行表达式indexqualorig判断元组是否满足过滤条件,如果不满足则需要继续获取。

ExecEndIndexScan函数负责清理IndexScanState节点。主要执行流程如下。

(1) 清理元组占用的槽位。
(2) 关闭索引扫描描述子。
(3) 关闭索引(如果是分区表则需要关闭分区索引及分区映射)。
(4) 关闭表。

3. BitmapIndexScan算子

BitmapIndexScan算子通过位图索引做扫描操作,利用位图记录元组在存储页面的偏移位置,对应BitmapIndexScan计划节点。BitmapIndexScan算子相关的代码源文件是“nodeBitmapIndexScan.cpp”。BitmapIndexScan执行的结果是位图,该算子配合BitmapHeapScan算子获取位图对应的元组。算子对应的主要函数如表7-14所示。

表7-14 BitmapIndexScan算子主要函数

主要函数

说明

ExecInitBitmapIndexScan

初始化BitmapIndexScan状态节点

MultiExecBitmapIndexScan

获取所有元组位图

ExecEndBitmapIndexScan

清理BitmapIndexScan状态节点

ExecReScanIndexScan

重置BitmapIndexScan

ExecInitPartitionForBitmapIndexScan

初始化分区表类型

BitmapIndexScan算子对应的状态节点代码如下:

typedef struct BitmapIndexScanState {

ScanState ss; /* 节点状态标识 */

TIDBitmap* biss_result; /* 位图:扫描结果集 */

ScanKey biss_ScanKeys; /* 索引扫描过滤表达式 */

int biss_NumScanKeys; /* 索引扫描键数量 */

IndexRuntimeKeyInfo* biss_RuntimeKeys; /* 索引扫描运行时求值表达式 */

int biss_NumRuntimeKeys; /* 运行时索引扫描键数量 */

IndexArrayKeyInfo* biss_ArrayKeys;/* 扫描键数组 */

int biss_NumArrayKeys; /* 数组长度 */

bool biss_RuntimeKeysReady; /* 运行时扫描键已经计算标识 */

ExprContext* biss_RuntimeContext; /* 求值表达式上下文 */

Relation biss_RelationDesc; /* 索引描述 */

List* biss_IndexPartitionList; /* 分区表对应索引 */

LOCKMODE lockMode; /* 锁模式 */

Relation biss_CurrentIndexPartition; /* 当前对应分区索引 */

} BitmapIndexScanState;

ExecInitBitmapIndexScan函数初始化BitmapIndexScan状态节点(BitmapIndexScanState)。主要执行流程如下。

(1) 创建BitmapIndexScanState节点用于存储状态信息。
(2) 打开索引。
(3) 构建索引扫描Key。
(4) 启动索引扫描(返回索引扫描描述符IndexScanDesc)。
(5) 把过滤Key传递给索引器。

MultiExecBitmapIndexScan函数返回所有元组位图。主要执行流程如下。

(1) 准备Bitmap结果集,用于存储元组ID。
(2) 步循环批量获取元组并存储于Bitmap结果集。如果有多组过滤Key(使用函数ExecIndexAdvanceArrayKeys判断)则继续循环批量获取元组。
posted @ 2024-04-30 10:35  openGauss-bot  阅读(16)  评论(0)    收藏  举报