訂閱
糾錯(cuò)
加入自媒體

PG:表訪問方法API如何進(jìn)行順序掃描?

2021-03-05 09:57
yzsDBA
關(guān)注

引言

PG中有很多方法檢索數(shù)據(jù)并返回給用戶。依賴于用戶的SQL語句,查詢計(jì)劃模塊生成最有方法以檢索請求的數(shù)據(jù)。順序掃描是用戶請求大量數(shù)據(jù)時(shí)或者當(dāng)表沒有索引時(shí)使用的一種檢索方法(例如select * from tablename;);順序掃描方法由表的表訪問方法APIchuli,heap表訪問方法時(shí)當(dāng)前版本中默認(rèn)的方法。本文中,將會介紹表訪問方法API如何進(jìn)行順序掃描。

PG中表訪問方法APIs

PG12中引入了可拔插表訪問方法,允許開發(fā)者重定義存儲/檢索表數(shù)據(jù)的方法。這個(gè)API包含42個(gè)函數(shù)。定義在tableam.h中,這些接口函數(shù)在typedef struct TableAmRoutine中。下面介紹關(guān)于順序掃描的routine,幫助開發(fā)這了解如何創(chuàng)建自己的表訪問方法。

順序掃描的調(diào)用棧

42個(gè)routines中很少由一個(gè)會被執(zhí)行器調(diào)用來完成順序掃描的請求。本節(jié)按調(diào)用順序描述這些接口。

relation_size

函數(shù)聲明:uint64  (*relation_size) (Relation rel, ForkNumberforkNumber);

Relation_size函數(shù)是第一個(gè)被調(diào)用的函數(shù),相對簡單。通過rel和forkNumber,返回對于文件的大學(xué)。默認(rèn)heap表訪問方法會調(diào)用存儲管理器smgr,計(jì)算出對于表文件的頁數(shù),然后成語每個(gè)頁大小BLCKSZ默認(rèn)8KB。如果不確定表和forknumber之間的關(guān)系,可以查詢網(wǎng)址https://www.highgo.ca/2020/10/23/free-space-mapping-file-in-details/了解更多信息。

返回的大小設(shè)置順序掃描的邊界。

slot_callbacks

函數(shù)聲明:const TupleTableSlotOps*(*slot_callbacks) (Relation rel);

下一步,執(zhí)行器需要找出此表訪問方法與哪一個(gè)tuple table slot(TTS)回調(diào)操作的集合兼容。TTS是routines集合,確保tuple存儲在執(zhí)行器和訪問方法之間兼容。執(zhí)行器執(zhí)行TTS回調(diào)以TupleTableSlot結(jié)構(gòu)傳輸tuple,該結(jié)構(gòu)執(zhí)行器可以認(rèn)識。默認(rèn)的heap訪問方法使用execTuples.c中定義的TTSOpsBufferHeapTuple來處理這個(gè)操作。

scan_begin

函數(shù)聲明:TableScanDesc (*scan_begin) (Relationrel,

                               Snapshotsnapshot,

                               int nkeys,struct ScanKeyData *key,

                              ParallelTableScanDesc pscan,

                              uint32flags);

現(xiàn)在可以開始掃描。這個(gè)函數(shù)是順序掃描的初始化函數(shù),將使用執(zhí)行器傳輸?shù)膮?shù)分配一個(gè)新的scan描述符。Scan描述符結(jié)構(gòu)的目的在于執(zhí)行順序掃描時(shí)進(jìn)行跟蹤。例如,要跟蹤從哪里開始掃描,上次掃描塊號是什么時(shí)候,應(yīng)該回復(fù)掃描哪個(gè)塊,以及掃描了多少塊等等。一旦順序掃描完成,scan描述符會被銷毀。

執(zhí)行器希望接口返回指向TableScanDesc結(jié)構(gòu)的指針。

scan_getnextslot

函數(shù)聲明:bool        (*scan_getnextslot) (TableScanDescscan,

                                   ScanDirection direction,

                                  TupleTableSlot *slot);

這個(gè)函數(shù)是順序掃描的主要函數(shù),從buffer管理器中獲取一個(gè)tuple,轉(zhuǎn)換成TTS格式并將它存儲到slot指針中。每次調(diào)用返回一個(gè)tuple。如果表由1000個(gè)tuple,這個(gè)函數(shù)會調(diào)用1000次。返回true表示需要再次調(diào)用獲取下一個(gè)tuple,返回false表示獲取了所有元組,不用再調(diào)用這個(gè)函數(shù)了。

通常情況下順序掃描以per-page模式進(jìn)行工作。也就是說從buffer管理器中加載并讀入一個(gè)block到內(nèi)存,然后從這個(gè)頁中一個(gè)元組一個(gè)元組地進(jìn)行返回,獲取完一頁,再加載另一頁進(jìn)行掃描。

Scan描述符起著重要作用,因?yàn)檫@個(gè)結(jié)構(gòu)體中存有大量控制信息,調(diào)用scan_getnextslot會更新。

scan_end

函數(shù)聲明:void        (*scan_end) (TableScanDesc scan);

順序掃描調(diào)用的最后一個(gè)函數(shù),用于清理scan描述符。此時(shí)執(zhí)行器已經(jīng)通過順序掃描方法獲取了所有元組信息。

準(zhǔn)備返回的數(shù)據(jù)

現(xiàn)在執(zhí)行器通過表訪問方法掃描了所有元組,需要進(jìn)入過濾流程決定哪些元組符合返回的條件(例如使用WHERE限制掃描結(jié)果)。由execScan.c中的for循環(huán)在每個(gè)TTS上執(zhí)行ExecQual,最終結(jié)果發(fā)送給用戶。

總結(jié)

流程圖如下:

聲明: 本文由入駐維科號的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報(bào)。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個(gè)字

您提交的評論過于頻繁,請輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯(cuò)
x
*文字標(biāo)題:
*糾錯(cuò)內(nèi)容:
聯(lián)系郵箱:
*驗(yàn) 證 碼:

粵公網(wǎng)安備 44030502002758號