复合索引对第一字段的查询是否也有用?


86

假设我有一个包含字段A和的表格B。我在A+ 上进行常规查询B,因此在上创建了一个复合索引(A,B)A组合索引还会仅对查询进行完全优化吗?

此外,我在上创建了索引A,但Postgres仍然仅在上将复合索引用于查询A。如果前面的答案是肯定的,那么我认为这并不重要,但是如果单个A索引可用,为什么默认情况下为什么要选择复合索引呢?


我试图为此设置一个小测试。但是,在我的情况下,仅当我删除单列索引1时才使用二列索引,该索引与首先创建的索引无关。有趣的是,如果我首先创建了两列索引,则初始计划将使用位图堆扫描。如果创建了单列索引,则运行查询(使用索引扫描)并删除新创建的索引,涉及两列索引的计划将切换为索引扫描。请参阅SQLFiddle
2012年

@dezso有趣。每个查询的费用在哪里?
卢西亚诺

位图索引扫描成本:107.98,43 ms执行时间。索引扫描一栏:费用为8.69,两栏:43.69。执行时间没有显着差异(波动大于两者之间的差异)。
dezso 2012年

@Luciano可以显示explain analyze和查询文本吗?
Craig Ringer

Answers:


88

必然是。我们在以下相关问题下进行了详细讨论:

以的倍数分配空间MAXALIGN,在64位OS上通常为8字节,在32位OS上通常为4字节(少得多)。如果不确定,请检查pg_controldata。它还取决于索引列的数据类型(有些需要对齐填充)和实际内容。

例如,两integer列(每个4字节)上的索引通常与一个索引上的索引完全一样,在索引上,另外4个字节因对齐填充而丢失。

在这种情况下,查询计划者使用index on- (a,b)与just index相比确实没有任何缺点(a)。而且通常最好是多个查询使用相同的索引。共享时,它(或其中的一部分)驻留在(快速)缓存中的机会会增加。

如果您已经在上保留了一个索引(a,b),则仅在该索引上创建另一个索引是没有意义的(a)-除非它实质上较小。同样是没有真正的(b,a)主场迎战(a)。按照第一行中的链接获取更多信息。

从相反的方向来看,当您需要一个类似on的附加索引时(a,b),请考虑(a)(如果可能)仅将一个现有索引放在上。通常是不可能的,因为那是PK或UNIQUE约束的索引。从Postgres 11开始,您可能只想bINCLUDE子句附加到约束定义就可以了。手册中的详细信息。

或在上创建新索引(b,a)以仅覆盖其他查询b。仅对于相等条件,btree索引中的索引表达式的顺序无关紧要。但是,当涉及范围条件时,它确实会。看到:

潜在的不利因素,以包括其他列的索引,即使只使用,否则失去了对齐填充空间:

  • 每当更新附加列时,索引现在也需要更新,这可能会增加写入操作的成本并造成更多索引膨胀。
  • 当涉及任何索引列时,无法在表上进行HOT更新(仅堆元组)。

有关HOT更新的更多信息:

如何测量物体尺寸:


1
您是否可以这样说:如果我在A列上有一个索引,并且有必要添加一个复合索引(A,B),那么应该删除索引A?如果重用索引提高了缓存效率,并且(A,B)完全优化了A,那么似乎在A上附加索引将浪费空间并可能减慢速度
jvans

1
@jvans:通常为true-带有明显的例外和替代方法。我添加了一个段落来解决这个问题。
Erwin Brandstetter,

2

根据您的问题,您有一个包含字段A和B的表。如果您的查询是:

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

优化程序将选择Composite索引,以避免Extract随机访问!


-4

如果仅在谓词中仅使用第一个,就属于这种情况。

如果您使用复合键的第一列和复合键的非键列,它将进行扫描。

要欺骗它,您可以只像这样伪造谓词,然后再伪列:

[A,B]是您的索引,[C]-另一列

要利用索引,您可以这样写:

SELECT
    A,B,C,D,E
FROM 
    test
WHERE
   A=1
AND
   B=B
AND 
   C=3

...如果单个A索引可用,为什么默认情况下为什么要选择复合索引?

仅在存在一个或两个谓词[A]或[A],[B]的情况下才使用索引。它不会按[B],[A]或[A],[C]的顺序使用它。为了能够使用带有附加列[C]的索引,您需要通过将谓词排序为[A],[B]和[C]来强制执行索引。


2
您到底能实现B=B什么?我认为您没有实现任何目标,因此我投了赞成票,没有任何证据不会被优化程序所忽略
Jack Douglas

2
B=B实际上与相同B IS NOT NULL,这似乎是不必要的。当然不需要在上使用索引(a,b)
Erwin Brandstetter 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.