在索引掃描中,索引存取方法負責傳回所有與掃描鍵相符的 tuple 的 TID。存取方法不參與實際從索引的父資料表提取這些 tuple,也不參與確定它們是否通過掃描的可見性測試或其他條件。
掃描鍵是 WHERE
子句的內部表示,其形式為 index_key
operator
constant
,其中索引鍵是索引的其中一個欄位,而運算子是與該索引欄位相關聯的運算子族群的其中一個成員。索引掃描有零或多個掃描鍵,這些掃描鍵隱含地以 AND 連接 — 預期傳回的 tuple 會滿足所有指示的條件。
存取方法可以報告索引對於特定查詢是有損的,或者需要重新檢查。這表示索引掃描將傳回所有通過掃描鍵的項目,再加上可能不符合的其他項目。核心系統的索引掃描機制接著會再次將索引條件應用於堆積 tuple,以驗證它是否真的應該被選取。如果未指定重新檢查選項,則索引掃描必須準確地傳回符合項目的集合。
請注意,完全由存取方法來確保它正確地找到所有且僅找到通過所有給定掃描鍵的項目。此外,核心系統只會交出所有與索引鍵和運算子族群相符的 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
必須傳回索引中最後一個相符的 tuple,而不是像通常那樣傳回第一個。(這只會發生在將 amcanorder
設定為 true 的存取方法上。)在第一次呼叫之後,amgettuple
必須準備好從最近傳回的項目開始在任一方向上推進掃描。(但是如果 amcanbackward
為 false,則所有後續呼叫都將與第一次呼叫的方向相同。)
支援有序掃描的存取方法必須支援在掃描中「標記」一個位置,並稍後返回到標記的位置。同一個位置可能會被還原多次。但是,每次掃描只需要記住一個位置;新的 ammarkpos
呼叫會覆蓋先前標記的位置。不支援有序掃描的存取方法,不需要在 IndexAmRoutine
中提供 ammarkpos
和 amrestrpos
函式;請將這些指標設為 NULL。
掃描位置和標記位置(如果有的話)都必須在索引中同時插入或刪除的情況下保持一致。如果一個新插入的條目,在掃描開始時就存在的話,掃描可以找到該條目,但是掃描沒有返回,這是可以接受的。或者掃描在重新掃描或倒退時,返回了這個條目,即使它第一次掃描時沒有被返回,也是可以接受的。同樣地,一個同時進行的刪除可能會或可能不會反映在掃描結果中。重要的是,插入或刪除操作不會導致掃描遺漏或重複返回那些沒有被插入或刪除的條目。
如果索引儲存了原始的索引資料值(而不是它們的一些有損表示),那麼支援僅索引掃描會很有用,在這種掃描中,索引會返回實際資料,而不僅僅是堆積元組的 TID。只有當可見性映射表顯示該 TID 位於一個全可見的頁面上時,才能避免 I/O;否則,無論如何都必須訪問堆積元組來檢查 MVCC 可見性。但這不是存取方法所關心的。
索引掃描可以使用 amgetbitmap
而不是 amgettuple
來完成,以便在一次呼叫中獲取所有元組。這可能比 amgettuple
明顯更有效,因為它可以避免在存取方法中進行鎖定/解鎖迴圈。原則上,amgetbitmap
應該與重複的 amgettuple
呼叫具有相同的效果,但我們施加了幾個限制來簡化問題。首先,amgetbitmap
一次返回所有元組,並且不支援標記或還原掃描位置。其次,元組在位元圖中返回,位元圖沒有任何特定的順序,這就是為什麼 amgetbitmap
不接受 direction
參數的原因。(排序運算符也不會為這種掃描提供。)此外,沒有提供使用 amgetbitmap
進行僅索引掃描的功能,因為沒有辦法返回索引元組的內容。最後,amgetbitmap
不保證對返回的元組進行任何鎖定,其含義在第 62.4 節中闡述。
請注意,如果存取方法的內部實現不適合其中一個 API,則允許存取方法僅實現 amgetbitmap
而不實現 amgettuple
,反之亦然。
如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的地方,請使用此表單來報告文件問題。