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 次 |
最近记录: |