?
Dokumen ini menggunakan Manual laman web PHP Cina Lepaskan
一個(gè)索引可以定義在表中多個(gè)字段上。比如,如果有以下格式的表:
CREATE TABLE test2 ( major int, minor int, name varchar );
顯而易見,/dev目錄被保存在一個(gè)數(shù)據(jù)庫(kù)里,并且你經(jīng)常做下面這樣的查詢:
SELECT name FROM test2 WHERE major = constant AND minor = constant;
那么在字段major和minor上聯(lián)合定義一個(gè)索引是比較合適的做法,也就是:
CREATE INDEX test2_mm_idx ON test2 (major, minor);
目前,只有B-tree,GiST和GIN支持多字段索引。 最多可以聲明32個(gè)字段(這個(gè)限制可以在編譯PostgreSQL時(shí)改變, 見pg_config_manual.h文件)。
一個(gè)多字段的B-tree索引可以用在包含索引字段子集的查詢條件里,不過(guò),如果在前導(dǎo)字段(最左邊)上有約束條件,那么效率最高。 準(zhǔn)確的規(guī)則是前導(dǎo)字段上的等于約束,加上第一個(gè)沒(méi)有等于約束的非等于約束字段,將用于限制所掃描的索引范圍。 將檢查這兩個(gè)字段右邊字段上的索引以減少對(duì)表的訪問(wèn),但是并不減少需要掃描的索引。 比如,假如我們有一個(gè)在(a, b, c)上的索引,查詢條件是WHERE a = 5 AND b >= 42 AND c < 77, 那么索引就需要先掃描所有a = 5且b = 42 ,直到所有a = 5的記錄掃描完畢。那些 c >= 77 的索引條目將被忽略,但是他們?nèi)匀粫?huì)被掃描。 這個(gè)索引原則上仍然會(huì)被用于那些在b和/或c上有約束,但是在a上沒(méi)有約束的查詢—,但是就必須掃描整個(gè)索引了。 因此,在大多數(shù)這種情況下,優(yōu)化器會(huì)選擇順序掃描表,而不使用索引。
一個(gè)多字段的GiST索引只能用于那些在前導(dǎo)字段上有查詢條件的查詢中。 附加字段上的條件會(huì)限制索引返回的條目,但是第一個(gè)字段上的條件是決定需要掃描多少索引內(nèi)容的最重要的字段。 如果在第一個(gè)字段上只有很少的一些唯一的數(shù)值,那么GiST就相對(duì)來(lái)說(shuō)不那么高效了,即使在附加字段上有許多獨(dú)立的數(shù)值也如此。
多字段GIN索引可用于涉及任何索引列子集的查詢條件。與B-tree或GIST不同,不管使用的索引列的查詢條件,索引搜索的有效性是相同的。
當(dāng)然,每個(gè)字段都必須和適合該索引類型的操作符一起使用;包含其它操作符的子句將不會(huì)被考慮。
使用多字段索引應(yīng)該謹(jǐn)慎。 在大多數(shù)情況下,在單字段上的索引就足夠了,并且還節(jié)約時(shí)間和空間。 除非表的使用模式非常固定,否則超過(guò)三個(gè)字段的索引幾乎沒(méi)什么用處。 見Section 11.5獲取有關(guān)不同索引設(shè)置的優(yōu)缺點(diǎn)的討論。