支援的版本:目前 (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 / 8.0 / 7.4 / 7.3 / 7.2

11.3. 多欄索引 #

索引可以定義在資料表的多個欄位上。 例如,如果您有一個如下形式的資料表

CREATE TABLE test2 (
  major int,
  minor int,
  name varchar
);

(假設您將 /dev 目錄保存在資料庫中...) 並且您經常發出類似這樣的查詢

SELECT name FROM test2 WHERE major = constant AND minor = constant;

那麼在欄位 majorminor 上一起定義索引可能更合適,例如

CREATE INDEX test2_mm_idx ON test2 (major, minor);

目前,只有 B-tree、GiST、GIN 和 BRIN 索引類型支援多鍵欄索引。 是否可以有多個鍵欄與是否可以將 INCLUDE 欄添加到索引無關。 索引最多可以有 32 個欄位,包括 INCLUDE 欄位。 (這個限制可以在建置 PostgreSQL 時修改;請參閱檔案 pg_config_manual.h。)

多欄 B-tree 索引可以用於包含索引中任何欄位子集的查詢條件,但當限制條件在開頭(最左邊)的欄位上時,索引效率最高。 確切的規則是,開頭欄位上的等式限制條件,加上第一個沒有等式限制條件的欄位上的任何不等式限制條件,將用於限制掃描的索引部分。 這些欄位右側欄位上的限制條件會在索引中檢查,因此它們可以節省對資料表的訪問,但它們不會減少需要掃描的索引部分。 例如,給定一個在 (a, b, c) 上的索引,和一個查詢條件 WHERE a = 5 AND b >= 42 AND c < 77,則索引必須從第一個 a = 5 且 b = 42 的條目掃描到最後一個 a = 5 的條目。 c >= 77 的索引條目將被跳過,但仍然需要掃描。 原則上,此索引可用於對 b 和/或 c 有限制條件但對 a 沒有限制條件的查詢 — 但必須掃描整個索引,因此在大多數情況下,計畫器會傾向於使用循序資料表掃描而不是使用索引。

多欄 GiST 索引可以用於包含索引中任何欄位子集的查詢條件。 其他欄位上的條件會限制索引傳回的條目,但第一個欄位上的條件對於確定需要掃描多少索引是最重要的。 如果 GiST 索引的第一個欄位只有少數幾個不同的值,即使其他欄位中有許多不同的值,該索引的效率也會相對較低。

多欄 GIN 索引可以用於包含索引中任何欄位子集的查詢條件。 與 B-tree 或 GiST 不同,索引搜尋效率與查詢條件使用哪個或哪些索引欄位無關。

多欄 BRIN 索引可以用於包含索引中任何欄位子集的查詢條件。 與 GIN 類似,但與 B-tree 或 GiST 不同,索引搜尋效率與查詢條件使用哪個或哪些索引欄位無關。 擁有多个 BRIN 索引而不是在單個資料表上擁有一個多欄 BRIN 索引的唯一原因是要擁有不同的 pages_per_range 儲存參數。

當然,每個欄位都必須使用適用於索引類型的運算符; 不包含其他運算符的子句將不被考慮。

多欄索引應謹慎使用。 在大多數情況下,單個欄位上的索引就足夠了,並且可以節省空間和時間。 除非資料表的使用非常程式化,否則具有三個以上欄位的索引不太可能有所幫助。 另請參閱 第 11.5 節第 11.9 節,了解關於不同索引配置優點的一些討論。

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表單來報告文件問題。