?
本文檔使用 php中文網(wǎng)手冊(cè) 發(fā)布
索引訪問(wèn)方法必須提供的索引構(gòu)造和維護(hù)函數(shù)有:
IndexBuildResult * ambuild (Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo);
創(chuàng)建一個(gè)新索引。索引關(guān)系已經(jīng)物理上創(chuàng)建好了,但是是空的。必須用索引訪問(wèn)方
法要求的固定數(shù)據(jù)填充它,還有就是所有已經(jīng)在表里的行。通常,ambuild
函數(shù)會(huì)調(diào)用 IndexBuildHeapScan()
掃描該表以獲取現(xiàn)
有行并計(jì)算需要插入索引的鍵字。
bool aminsert (Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heapRelation, IndexUniqueCheck checkUnique);
向現(xiàn)有索引插入一個(gè)新行。values和isnull數(shù)組給出需要制作索引的鍵字值, 而 heap_tid 是要被索引的TID。 如果該訪問(wèn)方法支持唯一索引(它的 pg_am. amcanunique 標(biāo)志是真),那么checkUnique可以是真,在這種情況下, 該索引訪問(wèn)方法必須校驗(yàn)表中不存在沖突的行;參閱Section 51.5獲取細(xì)節(jié)。 通常在執(zhí)行唯一性檢查時(shí)訪問(wèn)方法僅僅需要heapRelation參數(shù)(盡管那時(shí)它將通過(guò)查堆來(lái) 檢查元組活性)。
這個(gè)函數(shù)的布爾結(jié)果值僅僅在checkUnique 是UNIQUE_CHECK_PARTIAL 時(shí)有意義。這種情況下一個(gè)“真”值意味著這個(gè)新條目是唯一可知的,反之,“假”意味著它可能不 是唯一的(而且一個(gè)延遲的唯一性校驗(yàn)必須是預(yù)定的)。對(duì)于其他情況的結(jié)果建議使用常量“假”。
有些索引可能不會(huì)為所有元組做索引。如果元組不被編入索引, aminsert
應(yīng)該什么都不做而僅僅返回。
IndexBulkDeleteResult * ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state);
從索引中刪除行。這是一個(gè)"大批刪除"的操作,通常都是通過(guò)掃描整個(gè)索引,檢查
每條記錄,看看它是否需要被刪除來(lái)實(shí)現(xiàn)的??梢哉{(diào)用傳遞進(jìn)來(lái)的callback函數(shù),調(diào)用風(fēng)格是:callback(TID,
callback_state)returns bool,其作用是判斷某個(gè)用其引用的 TID
標(biāo)識(shí)的索引條目是否需要?jiǎng)h除。必須返回 NULL 或者是一個(gè) palloc 出來(lái)的,
包含刪除操作之效果的統(tǒng)計(jì)的結(jié)構(gòu)。如果不需要向amvacuumcleanup
傳遞信息,返回NULL也是OK的。
由于maintenance_work_mem 的限制,在刪除多行的時(shí)候 ambulkdelete
可能需要被調(diào)用多次,stats參數(shù)是先前在這
個(gè)索引上的調(diào)用結(jié)果(在一個(gè) VACUUM操作內(nèi)部第一次調(diào)用的話則
是 NULL)。這將允許 AM 在整個(gè)操作過(guò)程中積累統(tǒng)計(jì)信息。典型的,如果傳遞
的 stats 不是 null 的話,ambulkdelete
將會(huì)
修改并返回相同的結(jié)構(gòu)。
IndexBulkDeleteResult * amvacuumcleanup (IndexVacuumInfo *info, IndexBulkDeleteResult *stats);
在一個(gè)(置空)操作(一個(gè)或多個(gè) ambulkdelete
調(diào)用)之后清理。雖然不必做任何返回索引狀態(tài)之外的任何其他事情,但是它通常用于
批量清理,比如說(shuō)回收空的索引頁(yè)面。stats 是最后的 ambulkdelete
調(diào)用返回的東西或者NULL(如果因?yàn)闆](méi)有行需要?jiǎng)h除而未調(diào)用 ambulkdelete
的話)。如果結(jié)果不是NULL,那么它必須是一個(gè) palloc 出來(lái)的結(jié)構(gòu)。它包含的
統(tǒng)計(jì)信息將用于更新 pg_class并且由VACUUM報(bào)
告(如果給出了VERBOSE)。如果索引在VACUUM 操作
的過(guò)程中根本沒(méi)有改變,那么返回NULL也是可以的,否則必須返回當(dāng)前狀態(tài)。
在PostgreSQL8.4時(shí),amvacuumcleanup
將也會(huì)在一個(gè)ANALYZE完成時(shí)被調(diào)用。這時(shí)stats總是空
而且任何返回值都將會(huì)被忽略。這種情況可以通過(guò)檢測(cè)info->
analyze_only來(lái)區(qū)分。我們建議,在這樣的調(diào)用中訪問(wèn)方法除了做插入后
的清理外什么也不做,并且那是僅僅是在一個(gè)自動(dòng)清理的工作流程中。
void amcostestimate (PlannerInfo *root, IndexOptInfo *index, List *indexQuals, RelOptInfo *outer_rel, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation);
估算一個(gè)索引掃描的開(kāi)銷(xiāo)。該函數(shù)在下面的Section 51.6中有詳細(xì)的討論。
bytea * amoptions (ArrayType *reloptions, bool validate);
為一個(gè)索引分析和驗(yàn)證 reloptions 數(shù)組,僅當(dāng)一個(gè)索引存在非空reloptions數(shù) 組時(shí)才會(huì)被調(diào)用。reloptions是一個(gè)text數(shù)組,包含 name=value 格式的項(xiàng)。 該函數(shù)應(yīng)當(dāng)創(chuàng)建一個(gè)bytea值,該值將被拷貝進(jìn)索引的relcache項(xiàng)的 rd_options 字段。bytea值的數(shù)據(jù)內(nèi)容可以由訪問(wèn)方法定義, 不過(guò)目前所有的標(biāo)準(zhǔn)訪問(wèn)方法都使用StdRdOptions結(jié)構(gòu)。當(dāng) validate為真時(shí),如果任何一個(gè)選項(xiàng)不可識(shí)別或者含有非法值,該 函數(shù)都應(yīng)當(dāng)報(bào)告一個(gè)適當(dāng)?shù)腻e(cuò)誤信息;當(dāng)validate為假時(shí),非法 項(xiàng)應(yīng)該被悄悄的忽略。當(dāng)載入已經(jīng)存儲(chǔ)在pg_catalog中的選項(xiàng)時(shí), validate為假,僅在訪問(wèn)方法已經(jīng)改變了選項(xiàng)規(guī)則的時(shí)候才可能找 到非法項(xiàng),在此情況下可以忽略廢棄的項(xiàng)。如果默認(rèn)行為正是想要的,那么返回 NULL也OK。
索引的目的當(dāng)然是支持那些包含一個(gè)可以索引的WHERE條件 的行的掃描,這個(gè)條件通常叫修飾詞或 掃描鍵字。索引掃描的語(yǔ)義在下面的Section 51.3里面有更完整的描述。 一個(gè)索引訪問(wèn)方法必須提供的與掃描有關(guān)的函數(shù)有:
IndexScanDesc ambeginscan (Relation indexRelation, int nkeys, ScanKey key);
開(kāi)始一個(gè)新的掃描。key數(shù)組(長(zhǎng)度是 nkeys)為該索引掃
描描述索引鍵字(可能是多個(gè))。結(jié)果必須是一個(gè)palloc出來(lái)的結(jié)構(gòu)。
由于實(shí)現(xiàn)的原因,索引訪問(wèn)方法必須通過(guò)調(diào)用RelationGetIndexScan()
來(lái)創(chuàng)建這個(gè)結(jié)構(gòu)。在大多數(shù)情況下,amrescan
本身除了調(diào)用上面這個(gè)
函數(shù)之外幾乎不干別的事情;索引掃描啟動(dòng)時(shí)的有趣部分在amrescan
里。
boolean amgettuple (IndexScanDesc scan, ScanDirection direction);
在給出的掃描里抓取下一個(gè)行,向給出的方向移動(dòng)(在索引里向前或者向后)。如果抓取
到了行,則返回TRUE,如果沒(méi)有抓到匹配的行,返回FALSE。
在為T(mén)RUE的時(shí)候,該行的TID存儲(chǔ)在 scan 結(jié)構(gòu)里。請(qǐng)注意"成功"只
是意味著索引包含一個(gè)匹配掃描鍵字的條目,并不是說(shuō)該行仍然在堆中存在,
或者是能夠通過(guò)調(diào)用著的快照檢查(譯注:MVCC 快照,用于判斷事務(wù)邊界內(nèi)的行可視性)。
在成功時(shí),amgettuple
必須把 scan->xs_recheck 也設(shè)
置成TRUE或者FALSE。FSLSA意味著索引條目確定匹配搜索關(guān)鍵值。
TRUE意味著這并不確定,而且用搜索關(guān)鍵值表示的條件在被讀取之后必須再與堆元組核對(duì)。
這條規(guī)定支持"lossy"索引操作符。
注意復(fù)查僅僅對(duì)搜索條件擴(kuò)大;一個(gè)部分索引謂語(yǔ)(if any)從不被amgettuple
調(diào)用程序復(fù)查。
amgetbitmap
函數(shù)僅僅在訪問(wèn)方法支持"bitmap"索引掃描
時(shí)需要被提供。如果不是的話,在pg_am行的amgetbitmap
區(qū)域必須被設(shè)為零。
int64 amgetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
在給出的掃描抓取多個(gè)行并且把它們添加到提供的調(diào)用TIDBitmap
中去,返回獲取的元組的數(shù)量(這可能僅僅是一個(gè)粗略計(jì)數(shù),事實(shí)上一些AMs不會(huì)
檢測(cè)副本)。當(dāng)把元組地址插入到點(diǎn)陣時(shí),amgetbitmap
可以指明復(fù)校
掃描條件對(duì)特定的元組地址是必需的。 這個(gè)與amgettuple
的 xs_recheck輸出函數(shù)是相似的。注意:照當(dāng)前情況,維持這個(gè)特性是與維持維持位
圖本身的損壞存儲(chǔ)相關(guān)聯(lián)的,因而調(diào)用方會(huì)為可復(fù)核的元重新檢查掃描情況和部分索
引謂詞(若有的話)。無(wú)論如何,那不會(huì)總是為真。 amgetbitmap
和
amgettuple
不能被用于相同的索引掃描;正如在Section 51.3,當(dāng)使用amgetbitmap
的時(shí)候也有其他的限制條件。
amgetbitmap
函數(shù)僅僅在訪問(wèn)方法支持"bitmap"索引掃描時(shí)
需要被提供。如果不是的話,在pg_am行的 amgetbitmap區(qū)域必須被設(shè)為零。
void amrescan (IndexScanDesc scan, ScanKey key);
重啟開(kāi)始給出的掃描,可能使用的是一個(gè)新的掃描鍵字(要想繼續(xù)使用原來(lái)的鍵字,
給 key)傳遞一個(gè) NULL)。請(qǐng)注意,不可能改變鍵字的個(gè)數(shù)。實(shí)際上
這個(gè)重新開(kāi)始的特性是在一個(gè)嵌套循環(huán)連接選取了一個(gè)新的外層行,因此需要一個(gè)
新的鍵字比較值,但掃描鍵字的結(jié)構(gòu)仍然相同的時(shí)候使用的。這個(gè)函數(shù)也被
RelationGetIndexScan()
調(diào)用,因此這個(gè)函數(shù)既用于索引掃描的初
始化設(shè)置,也用于重復(fù)掃描。
void amendscan (IndexScanDesc scan);
結(jié)束掃描并釋放資源。不應(yīng)該釋放scan本身,但訪問(wèn)方法內(nèi)部使用的任 何鎖或者銷(xiāo)都應(yīng)該釋放。
void ammarkpos (IndexScanDesc scan);
標(biāo)記當(dāng)前掃描位置。訪問(wèn)方法只需要支持每次掃描里面有一個(gè)被記住的掃描位置。
void amrestrpos (IndexScanDesc scan);
把掃描恢復(fù)到最近標(biāo)記的位置。
通常,任何索引訪問(wèn)方法函數(shù)的pg_proc記錄都應(yīng)該顯示正確
數(shù)目的參數(shù),只是把類型都聲明為類型internal(因?yàn)榇蠖鄶?shù)參數(shù)的類型
都是 SQL 不識(shí)別的類型,并且不希望用戶直接調(diào)用該函數(shù))。返回類型根據(jù)具體情況
聲明為 void, internal, 或boolean。唯一的例外
是 amoptions
,它應(yīng)當(dāng)被聲明為接受 text[]和bool
并返回 bytea。這樣就允許客戶端代碼執(zhí)行 amoptions
以選項(xiàng)設(shè)置的有效性。