支持的版本: 当前 (17) / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2

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 节,其中讨论了不同索引配置的优点。

提交更正

如果您在文档中发现任何不正确、与特定功能的体验不符或需要进一步澄清的地方,请使用此表单报告文档问题。