2025年9月25日: PostgreSQL 18 釋出!
支援的版本:當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1

11.5. 組合多個索引 #

單個索引掃描只能使用查詢子句,這些子句使用索引的列,並帶有限定符類中的運算子,並且透過AND連線。例如,給定一個在(a, b)上的索引,像WHERE a = 5 AND b = 6這樣的查詢條件可以使用該索引,但像WHERE a = 5 OR b = 6這樣的查詢則不能直接使用該索引。

幸運的是,PostgreSQL能夠組合多個索引(包括多次使用同一索引)來處理無法透過單索引掃描實現的場景。系統可以對多個索引掃描形成ANDOR條件。例如,像WHERE x = 42 OR x = 47 OR x = 53 OR x = 99這樣的查詢可以分解為對x上索引的四次獨立掃描,每次掃描使用一個查詢子句。然後,將這些掃描的結果進行OR運算以生成結果。另一個例子是,如果我們分別在xy上有索引,對像WHERE x = 5 AND y = 6這樣的查詢的一種可能的實現方式是分別使用每個索引和相應的查詢子句,然後將索引結果進行AND運算來識別結果行。

為了組合多個索引,系統會掃描每個所需的索引,並在記憶體中準備一個點陣圖,其中包含報告與該索引條件匹配的錶行的位置。然後,根據查詢的需要,將這些點陣圖進行AND和OR運算。最後,訪問並返回實際的錶行。錶行會按物理順序訪問,因為點陣圖就是這樣佈局的;這意味著原始索引的任何排序都會丟失,如果查詢有ORDER BY子句,則需要一個單獨的排序步驟。因此,並且因為每個額外的索引掃描都會增加額外的時間,最佳化器有時會選擇使用簡單的索引掃描,即使有其他可用的索引本可以被使用。

在大多數應用中,可能存在各種有用的索引組合,資料庫開發人員必須進行權衡,決定提供哪些索引。有時多列索引是最佳選擇,但有時建立單獨的索引並依賴索引組合功能會更好。例如,如果你的工作負載包含查詢的混合,有時只涉及列x,有時只涉及列y,有時涉及兩列,你可能會選擇在xy上建立兩個單獨的索引,並依賴索引組合來處理使用兩列的查詢。你也可以在(x, y)上建立一個多列索引。對於涉及兩列的查詢,該索引通常比索引組合更高效,但如第 11.3 節所述,它對於僅涉及y的查詢用處較小。其有用程度取決於B-tree索引跳過掃描最佳化有多有效;如果x只有幾百個不同的值,跳過掃描將使搜尋特定y值的操作執行得相當高效。在(x, y)上的多列索引和y上的單獨索引的組合也可能效果不錯。對於僅涉及x的查詢,可以使用多列索引,儘管它會比僅在x上的索引更大,因此也更慢。最後一個選擇是建立所有三個索引,但這可能只在表被搜尋的頻率遠高於其被更新的頻率,並且這三種類型的查詢都很常見時才合理。如果其中一種查詢型別比其他型別少見得多,你可能會選擇只建立最符合常見型別的兩個索引。

提交更正

如果你在文件中發現任何不正確的內容,與你對特定功能的實際體驗不符,或者需要進一步澄清,請使用此表單報告文件問題。