支援版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援版本:12 / 11 / 10 / 9.6 / 9.5

58.1. 抽樣方法支援函數 #

TSM 處理常式函數會傳回一個 palloc 的 TsmRoutine 結構,其中包含指向下面描述的支援函數的指標。 大多數函數是必需的,但有些是可選的,這些指標可以為 NULL。

void
SampleScanGetSampleSize (PlannerInfo *root,
                         RelOptInfo *baserel,
                         List *paramexprs,
                         BlockNumber *pages,
                         double *tuples);

此函數在規劃期間被呼叫。 它必須估計在樣本掃描期間將讀取的關聯頁面數量,以及掃描將選擇的元組數量。(例如,這些可以透過估計抽樣比例來確定,然後將 baserel->pagesbaserel->tuples 數字乘以該比例,確保將結果四捨五入為整數值。)paramexprs 清單包含作為 TABLESAMPLE 子句參數的表達式。建議使用 estimate_expression_value() 來嘗試將這些表達式簡化為常數(如果需要它們的值來進行估計);但即使無法簡化它們,該函數也必須提供大小估計值,即使這些值看起來無效也不應失敗(請記住,它們只是執行時間值的估計值)。 pagestuples 參數是輸出。

void
InitSampleScan (SampleScanState *node,
                int eflags);

初始化以執行 SampleScan 計劃節點。 這在執行器啟動期間被呼叫。 它應該在處理開始之前執行任何需要的初始化。SampleScanState 節點已經被建立,但它的 tsm_state 欄位為 NULL。 InitSampleScan 函數可以 palloc 採樣方法需要的任何內部狀態資料,並將指向它的指標儲存在 node->tsm_state 中。 關於要掃描的表的信息可以透過 SampleScanState 節點的其他欄位訪問(但請注意,node->ss.ss_currentScanDesc 掃描描述符尚未設定)。 eflags 包含描述此計劃節點執行器操作模式的標誌位元。

(eflags & EXEC_FLAG_EXPLAIN_ONLY) 為 true 時,實際不會執行掃描,因此此函數應僅執行使節點狀態對於 EXPLAINEndSampleScan 有效所需的最小操作。

此函數可以省略(將指標設定為 NULL),在這種情況下,BeginSampleScan 必須執行採樣方法所需的所有初始化。

void
BeginSampleScan (SampleScanState *node,
                 Datum *params,
                 int nparams,
                 uint32 seed);

開始執行抽樣掃描。 這在第一次嘗試提取元組之前被呼叫,如果需要重新啟動掃描,則可以再次呼叫。 關於要掃描的表的信息可以透過 SampleScanState 節點的欄位訪問(但請注意,node->ss.ss_currentScanDesc 掃描描述符尚未設定)。 長度為 nparamsparams 陣列包含在 TABLESAMPLE 子句中提供的參數值。 這些將具有採樣方法的 parameterTypes 清單中指定的數字和類型,並且已經過檢查以確保不為 null。 seed 包含用於在採樣方法中產生的任何隨機數的種子; 如果給定了 REPEATABLE 值,則它是從該值衍生的雜湊值,否則它是 random() 的結果。

此函數可以調整欄位 node->use_bulkreadnode->use_pagemode。 如果 node->use_bulkreadtrue(預設值),則掃描將使用一種緩衝區訪問策略,該策略鼓勵在使用後回收緩衝區。 如果掃描僅訪問表頁面的一小部分,則將其設定為 false 可能是合理的。 如果 node->use_pagemodetrue(預設值),則掃描將對每個訪問頁面上的所有元組執行單次通過的可見性檢查。 如果掃描僅選擇每個訪問頁面上元組的一小部分,則將其設定為 false 可能是合理的。 這將導致執行較少的元組可見性檢查,但由於它需要更多的鎖定,因此每個檢查將會更加昂貴。

如果採樣方法被標記為 repeatable_across_scans,則它必須能夠在重新掃描期間選擇與原始掃描相同的元組集合,也就是說,對 BeginSampleScan 的全新呼叫必須導致選擇與之前相同的元組(如果 TABLESAMPLE 參數和種子沒有改變)。

BlockNumber
NextSampleBlock (SampleScanState *node, BlockNumber nblocks);

傳回要掃描的下一個頁面的區塊編號,如果沒有頁面要掃描,則傳回 InvalidBlockNumber

此函數可以省略(將指標設定為 NULL),在這種情況下,核心程式碼將執行整個關聯的循序掃描。 這種掃描可以使用同步掃描,因此採樣方法不能假設關聯頁面在每次掃描中都以相同的順序訪問。

OffsetNumber
NextSampleTuple (SampleScanState *node,
                 BlockNumber blockno,
                 OffsetNumber maxoffset);

傳回要在指定頁面上抽樣的下一個元組的偏移量編號,如果沒有元組要抽樣,則傳回 InvalidOffsetNumbermaxoffset 是頁面上使用的最大偏移量編號。

注意

沒有明確告知 NextSampleTuple1 .. maxoffset 範圍內的哪個偏移量編號實際包含有效的元組。 這通常不是問題,因為核心程式碼會忽略對遺失或不可見元組進行抽樣的請求; 這不應導致樣本中出現任何偏差。 但是,如果需要,該函數可以使用 node->donetuples 來檢查它傳回的元組中有多少是有效且可見的。

注意

NextSampleTuple 必須 假設 blockno 是最近一次 NextSampleBlock 呼叫傳回的相同頁面編號。 它是由先前的 NextSampleBlock 呼叫傳回的,但核心程式碼可以提前呼叫 NextSampleBlock,以便在實際掃描頁面之前,從而支援預取。 可以假設一旦開始抽樣給定的頁面,後續的 NextSampleTuple 呼叫都引用相同的頁面,直到傳回 InvalidOffsetNumber

void
EndSampleScan (SampleScanState *node);

結束掃描並釋放資源。通常釋放 palloc 分配的記憶體並不重要,但任何外部可見的資源都應清理乾淨。在沒有此類資源的常見情況下,可以省略此函數(將指標設置為 NULL)。

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清之處,請使用此表格來報告文件問題。