?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
在一個索引掃描里,索引訪問方法負(fù)責(zé)把它拿到的那些據(jù)說匹配掃描鍵字scan keys的所有行之 TID 的回流。訪問方法不not會卷入從索引的 父表中實(shí)際抓取這些行的動作中,也不會判斷他們是否通過了掃描的時間條件測試或者 是其它條件。
一個掃描鍵字是形如 index_key operator constant 的 WHERE 子句的內(nèi) 部表現(xiàn)形式,這里的索引鍵字是索引中的一個字段,而操作符是和該索引字段相關(guān)聯(lián)的 操作符類的一個成員。一個索引掃描擁有零個或者多個掃描鍵字,他們是隱含著 AND 的關(guān)系 —返回的行被認(rèn)為是滿所所有列出的條件的行。
操作符類可能會指出改索引對于某些特定的操作符是有損耗的;這就暗示著該索引掃 描會返回所有通過掃描鍵字的條目,加上一些可能沒通過掃描鍵字的條目。核心系統(tǒng) 的索引掃描機(jī)制然后就會再次在堆行上使用該操作符,以校驗(yàn)這些條目是否真正應(yīng)該 選取。對于無損耗的操作符,索引掃描必須返回全部匹配的條目,不需要重復(fù)校驗(yàn)。
請注意,確保找到所有條目以及確保所有條目都通過給出的掃描鍵字的條件完全是
訪問方法的責(zé)任。還有,核心系統(tǒng)將只是簡單的吧所有匹配掃描鍵字和操作符類的
WHERE子句傳遞過來,而不會做任何語義分析,以判斷他們是否冗余
或者是否相互矛盾。舉例來說,給出 WHERE WHERE x > 4 AND x >
14 ,這里的 x是一個 b-tree 索引字段,那么把第一個掃描鍵字
識別成冗余的和可拋棄的工作是 b-tree amrescan
函數(shù)的事。
amrescan
過程中所需要的預(yù)處理的范圍將由索引訪問方法把掃描鍵
字縮減為一個"正常"形式的具體需要而定。
一些訪問方法按照一個明確定義的順序來返回索引條目,其他的則不會。如果條目按分類順序返回, 訪問方法應(yīng)該設(shè)置pg_am。amcanorder 對指示為真因此它支持順 序掃描。所有這些訪問方法必須為其等式和排序操作使用可兼容b樹的模式編碼。
amgettuple
函數(shù)有一個direction參數(shù),它可以是
ForwardScanDirection(正常情況)或者BackwardScanDirection
。如果amrescan
之后的第一次調(diào)用聲明 BackwardScanDirection,那么匹配條件的索引記錄集是從后向前掃描的,而
不是通常的從前向后掃描,因此 amgettuple
必須返回索引中最后
的匹配行,而不是通常情況下的第一條。這些事情只會是那些設(shè)置了 pg_am.amcanbackward非零的,號稱自己支持排序掃描的訪問
方法上會發(fā)生。在第一次調(diào)用之后,amrescan
必須準(zhǔn)備從最近返回
的條目的位置開始,在兩個方向上進(jìn)行掃描步進(jìn)。(但假如pg_am。
amcanbackward是假,所有后來的調(diào)用將會有與第一個同樣的方位。)
支持有序掃描的訪問方法必須支持在掃描里“標(biāo)記”一個位置并且隨后返回到這個標(biāo)記
過的位置。同樣的位置可能會被重復(fù)多次還原。但是,每次掃描中只有一個位置需要
被記住;一個新的ammarkpos
調(diào)用重寫之前標(biāo)記的位置。一個不支持有
序掃描的訪問方法應(yīng)該仍然在pg_am中提供標(biāo)記和還原功能,但如果
被訪問它足以使他們拋出錯誤。
掃描位置和標(biāo)記位置(如果存在)都必須在面對索引中存在并發(fā)插入和刪除的時候保持 一致性。如果一條并發(fā)新插入的記錄并未被一次掃描返回(而如果掃描開始的時候該 記錄存在,則會被返回),或者說掃描通過重新掃描或者回頭掃描返回這樣的記錄—即 使它第一次跑的時候沒有返回這樣的行,對于系統(tǒng)來說,這些情況都是可以接受的。 類似的還有,一個并發(fā)的刪除可以反映,也可以不反應(yīng)一個掃描的結(jié)果。重要的是, 插入或者刪除不會導(dǎo)致掃描會略過或者重復(fù)返回本身不是被插入或者刪除的條目。
除了使用 amgettuple
,索引掃描可以通過amgetmulti
在一次調(diào)用中提取所有元組來完成。這樣做可能會比amgettuple
有顯
著的效率提升,因?yàn)樗梢员苊庠谠L問方法內(nèi)的加鎖/解鎖的循環(huán)。在原理上,
amgetmulti
應(yīng)該和重復(fù)調(diào)用 amgettuple
的效果相同,
不過我們強(qiáng)制了一些限制來簡化事情。首先,amgetmulti
同時返回
所有元組并且標(biāo)記或掃描不支持的掃描條件。第二,這些元組被返回到一個沒有任何
特定排序的位圖中,這就是amgetbitmap
不獲取direction
參數(shù)的原因。amgetmulti
并不保證在返回的行上的任何鎖定,這就暗示
著Section 51.4里面的事情。
注意下,對于一個訪問方法來說,如果他的內(nèi)部實(shí)現(xiàn)不適用于一個API或者另一個,
僅僅執(zhí)行amgetbitmap
而不執(zhí)行amgettuple
是被允許的
,或者反過來也是一樣的。