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

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-Tree、GiST、GIN 和 BRIN 索引类型支持多键列索引。是否可以有多个键列与是否可以将 INCLUDE 列添加到索引无关。索引最多可以有 32 列,包含 INCLUDE 列。(此限制可以在构建 PostgreSQL 时更改,请参阅文件 pg_config_manual.h。)

多列 B-Tree 索引可以用于包含索引的任意子集的列的查询条件,但当对前置(最左边的)列有约束时,索引的效率最高。具体规则是,前置列上的等式约束,加上没有相等约束的第一列上的任意不等式约束,将会用于限定要扫描的索引部分。这些列右侧的列的约束在索引中进行检查,因此它们可以节省对表本身的访问,但不会减少必须扫描的索引部分。例如,给定一个索引 (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 节,了解有关不同索引配置优点的一些讨论。