TSM 處理函式返回一個 palloc 分配的 TsmRoutine
結構,其中包含指向下面描述的支援函式的指標。大多數函式是必需的,但有些是可選的,這些指標可以為 NULL。
void SampleScanGetSampleSize (PlannerInfo *root, RelOptInfo *baserel, List *paramexprs, BlockNumber *pages, double *tuples);
此函式在規劃期間被呼叫。它必須估計在抽樣掃描期間將讀取的表頁數,以及掃描將選擇的元組數。(例如,這可以透過估計取樣分數,然後將 baserel->pages
和 baserel->tuples
數字乘以該分數來確定,確保將結果四捨五入為整數值。)paramexprs
列表包含 TABLESAMPLE
子句的引數表示式。如果需要表示式的值進行估算,建議使用 estimate_expression_value()
將這些表示式簡化為常量;但是,即使它們無法被簡化,該函式也必須提供大小估算,並且即使值看起來無效也不應失敗(請記住,它們只是對執行時值的估算)。pages
和 tuples
引數是輸出引數。
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)
為真時,實際上不會執行掃描,因此此函式僅應執行最少的操作,以使節點狀態對於 EXPLAIN
和 EndSampleScan
有效。
此函式可以省略(將指標設定為 NULL),在這種情況下,BeginSampleScan
必須執行取樣方法所需的所有初始化。
void BeginSampleScan (SampleScanState *node, Datum *params, int nparams, uint32 seed);
開始執行取樣掃描。這在嘗試獲取第一個元組之前被呼叫,並且在掃描需要重新啟動時可能會再次被呼叫。有關要掃描的表的資訊可以透過 SampleScanState
節點的欄位訪問(但請注意,node->ss.ss_currentScanDesc
掃描描述符尚未設定)。params
陣列(長度為 nparams
)包含 TABLESAMPLE
子句中提供的引數的值。它們將具有采樣方法的 parameterTypes
列表中指定的數量和型別,並且已經過檢查,不為 NULL。seed
包含用於取樣方法中生成的任何隨機數的種子;如果提供了 REPEATABLE
值,則它是從該值派生的雜湊,否則它是 random()
的結果。
此函式可以調整 node->use_bulkread
和 node->use_pagemode
欄位。如果 node->use_bulkread
為 true
(預設值),則掃描將使用鼓勵在使用後回收緩衝區的緩衝區訪問策略。如果掃描只訪問表的一小部分頁面,則將此設定為 false
可能是合理的。如果 node->use_pagemode
為 true
(預設值),則掃描將在所有訪問的頁面上對所有元組進行單次可見性檢查。如果掃描只選擇每訪問頁面上的一小部分元組,則將此設定為 false
可能是合理的。這將導致執行的元組可見性檢查次數更少,儘管每次檢查的成本更高,因為它需要更多的鎖定。
如果取樣方法被標記為 repeatable_across_scans
,那麼它必須能夠在重新掃描時選擇與原始掃描相同的元組集,也就是說,在 BeginSampleScan
被重新呼叫後,必須選擇與之前相同的元組(如果 TABLESAMPLE
引數和種子沒有改變)。
BlockNumber NextSampleBlock (SampleScanState *node, BlockNumber nblocks);
返回下一個要掃描的頁的塊號,如果沒有剩餘的頁要掃描,則返回 InvalidBlockNumber
。
此函式可以省略(將指標設定為 NULL),在這種情況下,核心程式碼將對整個關係執行順序掃描。這種掃描可以使用同步掃描,因此取樣方法不能假定關係頁面在每次掃描時都以相同的順序訪問。
OffsetNumber NextSampleTuple (SampleScanState *node, BlockNumber blockno, OffsetNumber maxoffset);
返回指定頁面上下一個要取樣的元組的偏移號,如果沒有剩餘的元組要取樣,則返回 InvalidOffsetNumber
。maxoffset
是頁面上使用的最大偏移號。
NextSampleTuple
沒有明確知道 1 .. maxoffset
範圍內的哪些偏移量實際包含有效元組。這通常不是問題,因為核心程式碼會忽略對缺失或不可見元組的取樣請求;這不應導致樣本出現任何偏差。但是,如果需要,該函式可以使用 node->donetuples
來檢查它返回的元組中有多少是有效的和可見的。
NextSampleTuple
不能 假定 blockno
是上一次 NextSampleBlock
呼叫返回的相同頁面號。它是從之前的某個 NextSampleBlock
呼叫返回的,但核心程式碼允許在實際掃描頁面之前預先呼叫 NextSampleBlock
,以支援預取。可以假定一旦開始對某個頁面進行取樣, successive NextSampleTuple
呼叫都將引用同一個頁面,直到返回 InvalidOffsetNumber
。
void EndSampleScan (SampleScanState *node);
結束掃描並釋放資源。通常不需要釋放 palloc 分配的記憶體,但任何外部可見的資源都應被清理。此函式可以省略(將指標設定為 NULL),在通常情況下,沒有此類資源。
如果您在文件中發現任何不正確、不符合您使用該特定功能時的經驗或需要進一步說明的內容,請使用 此表單 報告文件問題。