在PostgreSQL中创建多列索引

arknldoa  于 2023-05-28  发布在  PostgreSQL
关注(0)|答案(2)|浏览(231)

我现在正在研究如何为我们的表创建索引。
我发现了多列索引,但我不确定影响。示例:
我们在findByIdfindByIdAndStatusfindByResult上有SQL。
它说WHERE上使用最多的应该在列列表中列出。但我想知道如果我为where子句的不同组合创建一个索引会不会有很大的影响。
这:(为所有对象创建一个索引)
CREATE INDEX CONCURRENTLY ON Students (id, status, result)
对比
这:(在不同的查询上创建不同的索引)
CREATE INDEX CONCURRENTLY ON Students (id)
CREATE INDEX CONCURRENTLY ON Students (status)
CREATE INDEX CONCURRENTLY ON Students (result)
非常感谢您的评分!

hi3rlvi2

hi3rlvi21#

为所有索引创建一个索引和创建不同的索引将对查询产生完全不同的影响。
1.您可以使用EXPLAIN查看查询是否使用了索引。

  1. This video非常适合了解DB索引。
    1.索引CREATE INDEX CONCURRENTLY ON仅当查询在WHERE子句中使用id、(id,status)或(id,status和result)时,才会使用Students(id,status,result)。状态为Where的查询根本不会使用此索引。
    索引基本上是平衡二叉树。多列索引将按id对行进行索引,然后按id排序的行将进一步按状态进行索引,然后按结果进行索引,依此类推。您可以看到,在此索引中,完全不存在排序via状态。它仅在以id的第一个索引的行上可用。
    看看视频,它很好地解释了这一切。
4bbkushb

4bbkushb2#

你读到的经验法则是错误的。
更好的规则是:只有在索引有用并且经常使用,值得在每个索引附带的数据修改上付出性能代价时,才创建这样的索引。
(a, b, c)上的多列B树索引在以下几种情况下很有用:
1.如果查询看起来像这样:

SELECT ... FROM tab
WHERE a = $1 AND b = $2 AND c <operator> $3

其中<operator>是索引支持的运算符,$1$2$3是常数。
1.如果查询看起来像这样:

SELECT ... FROM tab
WHERE a = $1 AND b = $2
ORDER BY c;

或者像这样

SELECT ... FROM tab
WHERE a = $1
ORDER BY b, c;

ORDER BY子句中的任何修饰都必须反映在CREATE INDEX语句中。例如,对于ORDER BY b, c DESC,必须在(a, b, c DESC)(a, b DESC, c)上创建索引(索引可以双向读取)。
1.如果查询看起来像这样:

SELECT c
FROM tab
WHERE a = $1 AND b <operator> $2;

如果该表是新的VACUUM艾德,这可以让你一个 * 索引只扫描 *,因为所有需要的信息都在索引中。
在最近的PostgreSQL版本中,这样的索引最好创建为

CREATE INDEX ON tab (a, b) INCLUDE (c);

相关问题