复合索引是否也适用于第一个字段的查询?

Luc*_*ano 104 postgresql performance index database-design index-tuning

假设我有一个包含字段A和的表B。我在A+上进行常规查询B,所以我在 上创建了一个复合索引(A,B)A复合索引是否也会对查询进行全面优化?

此外,我在 上创建了一个索引A,但 Postgres 仍然只使用复合索引来查询A。如果前面的答案是肯定的,我想这并不重要,但是为什么它默认选择复合索引,如果单个A索引可用?

Erw*_*ter 103

那当然是。我们在这个相关问题下详细讨论了这一点:

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

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

Postgres 13更新:新的索引重复数据删除改变了这一点。可以压缩重复的索引值。索引(a,b)通常较少重复,因此它从重复数据删除中获得的收益较少。
如果a是唯一列,重复数据删除不会有太大变化。(由于 MVCC 模型,仍然可能存在重复条目,同时只有一个对任何事务可见,因此添加b仍然可以产生较小的影响。)

除此之外,(a,b)与仅在(a). 并且通常优选多个查询使用相同的索引。当共享时,它(或它的一部分)驻留在(快速)缓存中的机会增加。

如果你已经维持了指数(a,b),那么它没有意义就只是创建另一个指标(a)-除非是显着变小。vs.情况并非如此。按照第一行中的链接了解更多信息。(b,a)(a)

从相反的方向来看,当您需要像 on 那样的附加索引时(a,b),请考虑将现有索引删除(a)- 如果可能的话。通常不可能,因为那是 PK 或UNIQUE约束的索引。从 Postgres 11 开始,您可能只需将子句附加b到约束定义即可INCLUDE手册中的详细信息。

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

在索引中包含额外的列有潜在的缺点,即使它只使用空间,否则会因对齐填充而丢失:

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

更多关于热更新:

如何测量物体尺寸: