一个索引可以定义在表的多个列上。例如,如果你有一个如下形式的表:
CREATE TABLE test2 ( major int, minor int, name varchar );
(假设你把/dev目录保存在数据库里……)并且经常发出如下查询:
SELECT name FROM test2 WHERE major =constantAND minor =constant;
那么将major和minor两列一起建一个索引可能是合适的,例如:
CREATE INDEX test2_mm_idx ON test2 (major, minor);
当前,只有 B-tree、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 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。
多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。
当然,每一列都必须配合适合该索引类型的操作符使用;涉及其他操作符的子句不会被考虑。
多列索引应谨慎使用。在大多数情况下,单列索引已经足够,而且更省空间、也更省时间。除非表的使用方式极其程式化,否则超过三列的索引通常不会有帮助。关于不同索引配置优缺点的讨论,还可参见Section 11.5和Section 11.9。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。