Postgresql

PostgreSQL 中的覆蓋索引是否有助於 JOIN 列?

  • March 25, 2022

我有很多看起來像這樣的表格:

CREATE TABLE table1(id INTEGER PRIMARY KEY, t1c1 INTEGER, t1c2 INTEGER);
CREATE TABLE table2(id INTEGER PRIMARY KEY, t1 INTEGER REFERENCES table1(id), t2c1 INTEGER);

我做了很多連接,我試圖過濾加入的表以從第一個表中獲取內容,如下所示:

SELECT t1c1
FROM table1
JOIN table2 ON table2.t1 = table1.id
WHERE t2c1 = 42;

當我為表編寫索引時,我會查看在 WHERE 子句中使用的列並建構索引以滿足它們。所以對於這個查詢,我最終會寫一個這樣的索引:

CREATE INDEX ON table2 (t2c1);

並且該索引至少可以在該查詢中使用。

我的問題是,如果我編寫這樣的索引:

CREATE INDEX ON table2 (t2c1, t1);

是否會將該索引用作覆蓋索引來幫助上述查詢中的 JOIN?我應該改變我的索引編寫策略來覆蓋外鍵列嗎?

是否會將該索引用作覆蓋索引來幫助上述查詢中的 JOIN?

這取決於。Postgres 將“僅索引”掃描作為索引訪問方法,直到 Postgres 10 本身都沒有“覆蓋索引”。

從 Postgres 11 開始,可以使用帶有列的真正覆蓋索引INCLUDE。Michael Paquier 的部落格文章介紹了該功能:

與程式碼範例相關的答案:

也就是說,索引CREATE INDEX ON table2 (t2c1, t1);對於您展示的查詢非常有意義。如果滿足其他先決條件,它可以用於僅索引掃描,也可以用於點陣圖索引掃描或普通索引掃描。有關的:

JOIN在 Postgres 中條件和WHERE條件幾乎完全等價。他們當然可以以同樣的方式使用索引。您可以重寫您的查詢:

SELECT t1.t1c1
FROM   table1 t1
JOIN   table2 t2 ON t2.t1 = t1.id
WHERE  t2.t2c1 = 42;

有了這個等價物:

SELECT t1.t1c1
FROM   table1 t1 CROSS JOIN table2 t2
WHERE  t2.t1 = t1.id
AND    t2.t2c1 = 42;

不過,第一種形式顯然更可取。更容易閱讀。

為什麼“幾乎”等價?(對於手頭的簡單查詢沒有區別。)

有關的:

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