PostgreSQL 采樣方法支持函數(shù)

2021-09-15 10:41 更新

TSM 處理器函數(shù)返回一個 palloc 好的TsmRoutine結(jié)構(gòu),其中包含 了下文所述的支持函數(shù)的指針。大部分函數(shù)是必須的,但是有些是可選的(它們 的指針可以為 NULL)。

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

這個函數(shù)在規(guī)劃期間被掉歐勇。它必須估計在一次采樣掃描中會被讀到的關(guān)系 頁面數(shù),以及將被該掃描所選擇的元組數(shù)(例如,可以先估計采樣分?jǐn)?shù), 乘上baserel->pagesbaserel->tuples 數(shù),并且把結(jié)果圓整)。paramexprs列表保存作為 TABLESAMPLE子句的參數(shù)的表達(dá)式。如果出于優(yōu)化的目的需要 這些表達(dá)式的值,我們推薦使用estimate_expression_value() 來嘗試將這些表達(dá)式變成常量。但是即便這些表達(dá)不能被簡化,該函數(shù)必須提供 估計的尺寸,并且即使出現(xiàn)不合法的值它也不應(yīng)該失敗(記住它們只是運(yùn)行時值 的估計)。pagestuples參數(shù)是輸出。

void
InitSampleScan (SampleScanState *node,
                int eflags);

為 SampleScan 計劃節(jié)點(diǎn)的執(zhí)行進(jìn)行初始化。這會在執(zhí)行器啟動時被調(diào)用。 它應(yīng)該執(zhí)行執(zhí)行處理啟動所需的任何初始化工作。 SampleScanState節(jié)點(diǎn)已經(jīng)被創(chuàng)建,但是它的 tsm_state域?yàn)?NULL。 InitSampleScan函數(shù)可以 palloc 任何采樣方法需要的內(nèi)部 狀態(tài)數(shù)據(jù),并且把它的一個指針存儲在 node->tsm_state中。有關(guān)要掃描的表的信息可以通過SampleScanState 節(jié)點(diǎn)的其他域訪問(但是要注意 node->ss.ss_currentScanDesc掃描描述符還沒有被設(shè)置)。 eflags包含描述這個計劃節(jié)點(diǎn)的執(zhí)行器操作模式的標(biāo)志位。

當(dāng)(eflags & EXEC_FLAG_EXPLAIN_ONLY)為真時,該 掃描將不會被真正執(zhí)行,因此這個函數(shù)應(yīng)該只做最少的事情,讓該節(jié)點(diǎn)狀態(tài)對 EXPLAINEndSampleScan可用。

這個函數(shù)可以被省略(把指針設(shè)置為 NULL),在那種情況下 BeginSampleScan必須執(zhí)行采樣方法所需的所有初始化工作。

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

開始執(zhí)行一次采樣掃描。就在第一次嘗試取得一個元組時就會調(diào)用這個函數(shù), 如果該掃描需要被重啟可能還要再次調(diào)用它。有關(guān)要掃描的表的信息可以通過 SampleScanState節(jié)點(diǎn)的其他域訪問(但是要注意 node->ss.ss_currentScanDesc掃描描述符還沒有被設(shè)置)。 長度為nparamsparams數(shù)組包含在 TABLESAMPLE子句中提供的參數(shù)的值。這些參數(shù)的編號和類型 在采樣方法的parameterTypes列表中指定,并且已經(jīng)被 檢查過不為空。seed包含用于在采樣方法中生成任何隨機(jī)數(shù)的 種子。如果給定了REPEATABLE值,種子將是該值的哈希。如果 沒有指定REPEATABLE值,種子將是 random()的 結(jié)果。

這個函數(shù)可能會調(diào)整域node->use_bulkread 以及node->use_pagemode。 如果node->use_bulkreadtrue(默認(rèn)), 該掃描將使用一種鼓勵重用緩沖區(qū)的緩沖區(qū)訪問策略。如果該掃描只訪問 該表的頁面的一小部分,將這個域設(shè)置為 false比較合理。 如果node->use_pagemodetrue(默認(rèn)), 那么對于每一個被訪問的頁面上的所有元組,該掃描將會在一趟中執(zhí)行它們 的可見性檢查。如果該掃描只選擇每個被訪問頁面上的一小部分,將這個域 設(shè)置為false比較合理。這將導(dǎo)致執(zhí)行較少次的元組可見性檢查, 但是每一次都會代價更大,因?yàn)樾枰噫i定。

如果采樣方法被標(biāo)記為repeatable_across_scans,在重 新掃描時,它必須能夠選擇和第一次掃描相同的元組集合,也就是說對 BeginSampleScan的一次新調(diào)用必須選擇和之前相同的元組 (如果TABLESAMPLE參數(shù)和種子沒有變化)。

BlockNumber
NextSampleBlock (SampleScanState *node, BlockNumber nblocks);

返回下一個要掃描的頁面的塊號,如果沒有剩余的頁面需要掃描則返回 InvalidBlockNumber。

這個函數(shù)可以被省略(設(shè)置指針為 NULL),在那種情況下核心代碼將 執(zhí)行整個關(guān)系的一次順序掃描。這樣一個掃描可以使用同步掃描,這樣 采樣方法不能假定每一次掃描都用同樣的順序訪問關(guān)系頁面。

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

返回指定頁面上下一個要被采樣的元組的偏移量,如果沒有剩余元組需要被采樣, 則返回InvalidOffsetNumber。maxoffset是頁面上 使用的最大偏移量。

注意

NextSampleTuple沒有被顯式地告知范圍 1 .. maxoffset中的哪些偏移量真正包含了合法的元組。這通常不 成問題,因?yàn)楹诵拇a會忽略采樣丟失或者不可見元組的請求。這不會導(dǎo)致采樣 中的任何偏差。 不過,如果必要,該函數(shù)可以用node->donetuples來檢查它返回的元組有多少是合法并且可見的。

注意

NextSampleTuple不能假定 blockno是最近一次NextSampleBlock調(diào)用返回的 同一個頁面號。它由之前某次NextSampleBlock調(diào)用所返回, 但是核心代碼被允許在真正掃描頁面之前調(diào)用 NextSampleBlock, 以便支持預(yù)取。假定一旦一個給定頁面的采樣開始,連續(xù)的 NextSampleTuple調(diào)用都將引用同一個頁面(直到返回 InvalidOffsetNumber)。

void
EndSampleScan (SampleScanState *node);

結(jié)束掃描并且釋放資源。釋放 palloc 過的內(nèi)存通常并不重要,但是任何外部 可見的資源應(yīng)該被清除。在沒有這類資源存在的通常情況下,這個函數(shù)可以被 省略(設(shè)置指針為 NULL)。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號