Postgresql

複合索引是否也適用於第一個欄位的查詢?

  • October 29, 2021

假設我有一個包含欄位AB. A我在+上進行定期查詢B,所以我在(A,B). 查詢是否A也會被複合索引完全優化?

此外,我在 上創建了一個索引A,但 Postgres 仍然使用複合索引僅在 上進行查詢A。如果前面的答案是肯定的,我想這並不重要,但是如果單A索引可用,為什麼預設選擇複合索引呢?

必然是。我們在這個相關問題下非常詳細地討論了這一點:

所有這些都適用於(預設)B-tree索引,而不是其他類型。

空間以 的倍數分配,MAXALIGN在 64 位作業系統上通常是 8 個字節,在 32 位作業系統上通常是 4 個字節(不太常見)。如果您不確定,請檢查pg_controldata. 它還取決於索引列的數據類型(有些需要對齊填充)和實際內容。

例如,兩integer列(每列 4 個字節)上的索引通常最終與僅一個上的索引一樣大,其中另外 4 個字節因對齊填充而失去。

Postgres 13更新:新的索引重複數據刪除改變了這一點。可以壓縮重複的索引值。索引上(a,b)的重複性通常較少,因此它從重複數據刪除中獲得的收益較少。

如果a是唯一列,則重複數據刪除不會有太大變化。(由於 MVCC 模型,仍然可能存在重複條目,任何事務同時只有一個可見,因此添加b仍然會有輕微影響。)

除此之外,查詢計劃器使用 on 上的索引實際上沒有缺點,(a,b)與 just 上的索引相比(a)。並且通常最好讓多個查詢使用相同的索引。共享時,它(或部分)駐留在(快速)記憶體中的機會會增加。

如果您已經在 上維護了一個索引(a,b),那麼在 just 上創建另一個索引是沒有意義的(a)- 除非它明顯更小。對於vs. 而言,情況並非如此。請點擊第一行中的連結了解更多資訊。(b,a)``(a)

從相反的方向來看,當您需要像 on 這樣的附加索引時(a,b),請考慮刪除現有索引 on just (a)- 如果可能的話。通常不可能,因為這是 PK 或UNIQUE約束的索引。從 Postgres 11 開始,您可能只需使用子句附加b到約束定義即可。手冊中的詳細資訊。INCLUDE

或者創建新索引來(b,a)代替僅覆蓋查詢b。僅對於相等條件,索引表達式的順序無關緊要。但是,在涉及範圍條件時確實如此。看:

在索引中包含額外的列有潛在的缺點,即使它只使用空間,否則會失去對齊填充:

  • 每當更新附加列時,索引現在也需要更新,這可能會增加寫入操作的成本並造成更多索引膨脹。
  • 涉及任何索引列時,無法對錶進行 HOT 更新(僅堆元組) 。

更多關於熱門更新:

如何測量物體尺寸:

根據您的問題,您有一個包含欄位 A 和 B 的表。如果您的查詢是:

SELECT * FROM [YOUR TBL]
WHERE A='XXXX'

優化器將選擇複合索引來避免提取隨機訪問!

引用自:https://dba.stackexchange.com/questions/27481