Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

11.3. 多列索引 #

可以针对表中的多列定义索引。例如,如果有一个如下所示的表

CREATE TABLE test2 (
  major int,
  minor int,
  name varchar
);

(比如说,您在数据库中保留了 /dev 目录...)并且您经常发出如下查询

SELECT name FROM test2 WHERE major = constant AND minor = constant;

那么,在列 majorminor 上一起定义索引可能是合适的,例如

CREATE INDEX test2_mm_idx ON test2 (major, minor);

目前,只有 B 树、GiST、GIN 和 BRIN 索引类型支持多键列索引。是否可以有多个键列与是否可以向索引中添加 INCLUDE 列无关。索引最多可以有 32 列,包括 INCLUDE 列。(在构建 PostgreSQL 时可以更改此限制;请参见文件 pg_config_manual.h。)

多列 B 树索引可用于涉及索引列任意子集的查询条件,但当对前导(最左)列有约束时,索引效率最高。确切的规则是,前导列上的相等性约束,加上没有相等性约束的第一列上的任何不等性约束,将用于限制扫描的索引部分。这些列右侧列上的约束在索引中检查,因此它们可以节省对表的访问,但不会减少必须扫描的索引部分。例如,给定 (a, b, c) 上的索引和查询条件 WHERE a = 5 AND b >= 42 AND c < 77,索引必须从 a = 5 和 b = 42 的第一个条目扫描到 a = 5 的最后一个条目。具有 c >= 77 的索引条目将被跳过,但仍然必须扫描它们。原则上,此索引可用于对 b 和/或 c 有约束而对 a 没有约束的查询 — 但必须扫描整个索引,因此在大多数情况下,计划程序更喜欢顺序表扫描而不是使用索引。

多列 GiST 索引可用于涉及索引列任意子集的查询条件。附加列上的条件限制索引返回的条目,但第一列上的条件是确定需要扫描多少索引的最重要条件。如果 GiST 索引的第一列只有几个不同的值,即使附加列中有许多不同的值,该索引也会相对无效。

多列 GIN 索引可用于涉及索引列任意子集的查询条件。与 B 树或 GiST 不同,无论查询条件使用哪个索引列,索引搜索效果都是相同的。

多列 BRIN 索引可用于涉及索引列任意子集的查询条件。与 GIN 类似,与 B 树或 GiST 不同,无论查询条件使用哪个索引列,索引搜索效果都是相同的。在单个表上拥有多个 BRIN 索引而不是一个多列 BRIN 索引的唯一原因是要有不同的 pages_per_range 存储参数。

当然,每个列都必须与适合索引类型的运算符一起使用;涉及其他运算符的子句将不被考虑。

应谨慎使用多列索引。在大多数情况下,单列索引就足够了,并且可以节省空间和时间。除非表的使用方式极其特殊,否则不太可能对包含三列以上的索引有所帮助。另请参阅第 11.5 节第 11.9 节,了解有关不同索引配置优点的一些讨论。