Postgresql 中文操作指南

11.3. Multicolumn Indexes #

可以对表中多个列定义索引。例如,如果你的表格具有以下形式:

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 存储参数。

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

多列索引应谨慎使用。在大多数情况下,单列索引足够用,并且可以节省空间和时间。只有当表的用途极其特别时,索引才可能超过三列。有关不同索引配置优势的一些讨论,请参见 Section 11.5Section 11.9