扫描算子----Nodetidscan.cpp解析

引言

上一篇文章中,我讲解了索引以及用到索引的IndexScan算子,这一篇文章我要讲述的TIDScan算子也和索引密不可分。

代码位置

src\gausskernel\runtime\executor\nodeTidscan.cpp

名词解释

TID

在GaussDB中,TID是指某一行记录所对应的地址,主要由两部分构成。分别是块地址和块内偏移地址。

src\include\storage\item\itemptr.h中找到其对应的结构体为ItemPointerData,定义如下

 
  1. //代码清单1
  2. typedef struct ItemPointerData {
  3. BlockIdData ip_blkid;
  4. OffsetNumber ip_posid;
  5. }

其中,ip_blkid代表块地址,ip_posid代表块内偏移地址。

聚集(聚簇)索引与非聚集(聚簇)索引

上一篇文章里对IndexScan算子的解析中我介绍了索引,但是并没有提到索引key-value中的value是什么。要弄清楚value对应的是什么内容,得先弄清楚聚集(聚簇)索引和非聚集(聚簇)索引。

简单地说,聚集(聚簇)索引是指直接定位到TID上的索引;非聚集(聚簇)索引是指间接定位到TID上的索引,通常其直接定位到主码。

下面我将通过一个具体例子来分析。

例如,有一个表如下所示:

IdNameAge
1Tom16
3Jack13
4Mary16

其中Id是主码(Primary Key)。并且每一个列上都建立了索引。

在此表中Id对应的索引是聚集(聚簇)索引,因为Id是主码,通过主码可以唯一找到一个行数据,因此通过Id可以查找到TID。而Name和Age所对应的索引是非聚集(聚簇)索引,非聚集(聚簇)索引通常定位到主码,例如,通过Name(Age)只能查找到Id,再通过Id查找TID对应的行数据。

过程可以通过一个简单的示意图说明。

聚集索引和非聚集索引

非聚集(聚簇)索引寻找行数据花费了2次索引时间,为什么其索引直接定位到TID呢?

当TID发生改变时,需要对索引表进行修改,如果所有索引都采用聚集(聚簇)索引,那么所有需要维护所有索引,所消耗的成本极大。将一部分聚集(聚簇)索引改成非聚集(聚簇)索引,则其他字段到主码字段的索引不需要修改,只需要修改主码到TID的索引,大大减少了维护索引表的开销。

功能作用

TIDScan算子主要用于遍历元组的物理存储位置(TID表),读取一个个元组。

主要函数为:

ExecInitTidScan初始化TIDScan状态结点
ExecTidScan迭代获取元组
ExecEndTidScan清理TIDSCan状态结点
ExecReScanTidScan重置TIDScan

ExecTidScan

关键函数为ExecTidScan,其主要代码如下

 
  1. //代码清单2
  2. TupleTableSlot* ExecTidScan(TidScanState* node)
  3. {
  4. return ExecScan(&node->ss, (ExecScanAccessMtd)TidNext, (ExecScanRecheckMtd)TidRecheck);
  5. }

输入参数

输入参数为TIDScan对应的状态结点TidScanState指针,查看其结构体定义

 
  1. //代码清单3
  2. typedef struct TidScanState {
  3. ScanState ss;
  4. List* tss_tidquals; /* 过滤表达式 */
  5. bool tss_isCurrentOf; /* 游标是否在当前扫描表中 */
  6. Relation tss_CurrentOf_CurrentPartition; /* 当前扫描分区*/
  7. int tss_NumTids; /* TID列表元素个数*/
  8. int tss_TidPtr; /* 当前扫描位置 */
  9. int tss_MarkTidPtr; /* 标记的扫描位置 */
  10. ItemPointerData* tss_TidList; /* TID列表*/
  11. /* 堆元组 */
  12. union {
  13. HeapTupleData tss_htup;
  14. UHeapTupleData tss_uhtup;
  15. };
  16. HeapTupleHeaderData tss_ctbuf_hdr; /* 堆元组头信息 */
  17. } TidScanState;

执行过程

执行过程比较简单,通过ExecScan函数调用ExecScanFetch函数,在ExecScanFetch函数中调用调用TidNext函数返回一个元组,回到ExecScan函数再进行元组投影,然后返回符合条件的元组。 执行过程图解如下。

TIDScan

小结

本篇文章我学习了聚集(聚簇)索引和非聚集(聚簇)索引,以及TID的结构和TIDScan算子的内容。下一篇文章,我将讲解与索引有关的BitmapScan相关的两个算子。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值