PostgreSQL 中的覆盖索引是否有助于 JOIN 列?

ldr*_*drg 13 postgresql index optimization

我有很多看起来像这样的表格:

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);
Run Code Online (Sandbox Code Playgroud)

我做了很多连接,我试图过滤连接表以从第一个表中获取内容,如下所示:

SELECT t1c1
FROM table1
JOIN table2 ON table2.t1 = table1.id
WHERE t2c1 = 42;
Run Code Online (Sandbox Code Playgroud)

当我为表编写索引时,我会查看 WHERE 子句中使用的列并构建索引以满足它们。所以对于这个查询,我最终会写一个这样的索引:

CREATE INDEX ON table2 (t2c1);
Run Code Online (Sandbox Code Playgroud)

并且这个索引至少有资格在该查询中使用。

我的问题是,如果我写这样的索引:

CREATE INDEX ON table2 (t2c1, t1);
Run Code Online (Sandbox Code Playgroud)

索引会不会作为覆盖索引来帮助上面查询中的JOIN?我应该改变我的索引编写策略来覆盖外键列吗?

Erw*_*ter 21

索引会不会作为覆盖索引来帮助上面查询中的JOIN?

这取决于。Postgres 将“仅索引”扫描作为索引访问方法,本身没有“覆盖索引”——直到 Postgres 10。

从 Postgres 11 开始,可以使用带有INCLUDE列的真正覆盖索引。Michael Paquier 的博客文章介绍了该功能:

与代码示例相关的答案:

也就是说,索引CREATE INDEX ON table2 (t2c1, t1);对于您演示的查询非常有意义。如果满足其他先决条件,它可以用于仅索引扫描,或者它可以用于位图索引扫描或普通索引扫描。有关的:

JOIN条件和WHERE条件在 Postgres中几乎完全相同。他们当然可以以同样的方式使用索引。您可以重写查询:

SELECT table1.t1c1
FROM   table1
JOIN   table2 ON table2.t1 = table1.id
WHERE  table2.t2c1 = 42;
Run Code Online (Sandbox Code Playgroud)

有了这个等价物:

SELECT table1.t1c1
FROM   table1 CROSS JOIN table2
WHERE  table2.t1 = table1.id
AND    table2.t2c1 = 42;
Run Code Online (Sandbox Code Playgroud)

不过,第一种形式显然更可取。更容易阅读。

为什么“几乎”相等?(对于手头的简单查询没有区别。)

有关的:


归档时间:

查看次数:

19923 次

最近记录:

4 年,9 月 前