在索引掃描中,索引訪問方法負責吐出它被告知的所有匹配掃描鍵的元組的 TID。訪問方法不負責實際從索引的父表獲取這些元組,也不負責確定它們是否通過了掃描的可見性測試或其他條件。
掃描鍵是形式為 index_key
operator
constant
的 WHERE
子句的內部表示,其中索引鍵是索引的列之一,而運算子是與該索引列關聯的運算子族成員之一。索引掃描具有零個或多個掃描鍵,它們是隱式 AND 運算的——預期的返回元組將滿足所有指示的條件。
訪問方法可以報告某個索引對於特定查詢是有損的,或者需要重新檢查。這意味著索引掃描將返回所有透過掃描鍵的條目,可能還會附加一些不匹配的條目。核心系統的索引掃描機制然後會再次將索引條件應用於堆元組,以驗證它是否確實應該被選中。如果未指定重新檢查選項,則索引掃描必須返回精確匹配的條目集。
請注意,完全由訪問方法負責確保它正確地找到並透過所有給定掃描鍵的所有條目,並且只找到這些條目。此外,核心系統只會傳遞與索引鍵和運算子族匹配的所有 WHERE
子句,而不會進行任何語義分析來確定它們是否冗餘或矛盾。例如,給定 WHERE x > 4 AND x > 14
,其中 x
是一個 b-tree 索引列,需要由 b-tree 的 amrescan
函式來識別第一個掃描鍵是冗餘的並可以被丟棄。在 amrescan
期間所需的預處理程度將取決於索引訪問方法在多大程度上需要將掃描鍵簡化為“規範化”形式。
某些訪問方法按明確定義的順序返回索引條目,而另一些則不。實際上,訪問方法支援排序輸出的兩種不同方式。
始終按其資料的自然順序返回條目的訪問方法(例如 btree)應將 amcanorder
設定為 true。目前,此類訪問方法必須為其相等和排序運算子使用與 btree 相容的策略編號。
支援排序運算子的訪問方法應將 amcanorderbyop
設定為 true。這表明索引能夠按滿足 ORDER BY
index_key
operator
constant
的順序返回條目。該形式的掃描修飾符可以如前所述傳遞給 amrescan
。
amgettuple
函式有一個 direction
引數,它可以是 ForwardScanDirection
(正常情況)或 BackwardScanDirection
。如果 amrescan
之後的第一次呼叫指定了 BackwardScanDirection
,那麼匹配的索引條目集將被從後向前掃描,而不是按正常的從前向後方向掃描,因此 amgettuple
必須返回索引中最後一個匹配的元組,而不是通常返回的第一個元組。(這僅會發生在將 amcanorder
設定為 true 的訪問方法上。)第一次呼叫後,amgettuple
必須能夠從最近返回的條目開始以任一方向推進掃描。(但如果 amcanbackward
為 false,則所有後續呼叫都將與第一次呼叫具有相同的方向。)
支援有序掃描的訪問方法必須支援“標記”掃描中的一個位置,並在以後返回到標記的位置。同一個位置可以被恢復多次。但是,每個掃描只需要記住一個位置;新的 ammarkpos
呼叫將覆蓋之前標記的位置。不支援有序掃描的訪問方法無需在 IndexAmRoutine
中提供 ammarkpos
和 amrestrpos
函式;而是將這些指標設定為 NULL。
掃描位置和標記位置(如果有)都必須在索引的併發插入或刪除時保持一致。如果一個剛剛插入的條目沒有被掃描返回(儘管在掃描開始時如果該條目存在它會被找到),或者掃描在重掃描或回溯時返回了這樣一個條目,即使它在第一次掃描時沒有被返回,這都是可以的。同樣,併發刪除可能會或可能不會在掃描結果中反映出來。重要的是插入或刪除不會導致掃描遺漏或重複返回本身沒有被插入或刪除的條目。
如果索引儲存了原始的索引資料值(而不是其有損表示),那麼支援索引僅掃描是很有用的,其中索引返回實際資料,而不僅僅是堆元組的 TID。只有當可見性圖顯示 TID 位於一個全可見頁面時,這才能避免 I/O;否則,為了檢查 MVCC 可見性,仍然必須訪問堆元組。但這與訪問方法無關。
而不是使用 amgettuple
,可以透過 amgetbitmap
來完成索引掃描,一次性獲取所有元組。這可能比 amgettuple
更有效率,因為它允許避免訪問方法內的鎖定/解鎖迴圈。原則上 amgetbitmap
應具有與重複呼叫 amgettuple
相同的效果,但我們施加了幾項限制以簡化事務。首先,amgetbitmap
一次性返回所有元組,不支援標記或恢復掃描位置。其次,元組以點陣圖的形式返回,該點陣圖沒有特定的順序,這就是為什麼 amgetbitmap
不接受 direction
引數的原因。(對於此類掃描,也不會提供排序運算子。)此外,amgetbitmap
沒有提供索引僅掃描的機制,因為無法返回索引元組的內容。最後,amgetbitmap
不保證對返回的元組進行任何鎖定,其影響在第 63.4 節中進行了說明。
請注意,允許訪問方法只實現 amgetbitmap
而不實現 amgettuple
,或者反之亦然,如果其內部實現不適合一種 API 或另一種 API。
如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用此表格報告文件問題。