9.3 9.4 9.5 9.6 10 11 12 13 14 15 16 17 Current(18)
PostgreSQL中文社区 问题报告 纠错本页面

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列。(该限制可以在源代码文件pg_config_manual.h中修改;请参见PostgreSQL的构建说明)。

多列 B-tree 索引可以与涉及索引列的任何子集的查询条件一起使用, 但当对前导(最左侧)列有约束时,索引的效率最高。确切的规则是, 对前导列的相等约束,加上对第一个没有相等约束的列的任何不等约束, 将始终用于限制扫描的索引部分。对这些列右侧列的约束会在索引中检查, 因此它们总是会节省对表的实际访问,但不一定会减少必须扫描的索引部分。 如果 B-tree 索引扫描能够有效地应用跳过扫描优化,它将在通过重复索引搜索 导航索引时应用每个列约束。这可以减少必须读取的索引部分,即使查询谓词 中的一个或多个列(在最不重要的索引列之前)缺少常规的相等约束。跳过扫描 通过在内部生成一个动态相等约束来工作,该约束匹配索引列中的每个可能值 (尽管仅在缺少来自查询谓词的相等约束的列时,并且仅当生成的约束可以与 查询谓词中的后续列约束结合使用时)。

例如,给定一个索引在 (x, y) 上,以及一个查询条件 WHERE y = 7700,B-tree 索引扫描可能能够应用跳过扫描优化。 这通常发生在查询规划器预计对每个可能的 N 值(或对 实际存储在索引中的每个 x 值)进行重复的 WHERE x = N AND y = 7700 搜索是最快的方法,考虑到表上 可用的索引。通常只有在存在如此少的不同 x 值时,规划器 才会采取这种方法,以至于它预计扫描将跳过大部分索引(因为大多数叶子页 不可能包含相关的元组)。如果有许多不同的 x 值,那么 整个索引将不得不被扫描,因此在大多数情况下,规划器将更倾向于顺序表扫描 而不是使用索引。

跳过扫描优化也可以选择性地应用,在具有来自查询谓词的至少一些有用约束的 B-tree 扫描中。例如,给定一个索引在 (a, b, c) 上,以及一个 查询条件 WHERE a = 5 AND b >= 42 AND c < 77,索引可能 必须从第一个条目开始扫描,其中 a = 5 和 b = 42, 一直到最后一个条目,其中 a = 5。索引条目中 c >= 77 的条目在表级别永远不需要过滤,但在索引中跳过它们 可能有利也可能没有利。当发生跳过时,扫描将开始一个新的索引搜索,以便 从当前 a = 5 和 b = N 分组的末尾重新定位 (即从索引中第一个元组 a = 5 AND b = N AND c >= 77 出现的位置), 到下一个此类分组的开始(即索引中第一个元组 a = 5 AND b = N + 1 出现的位置)。

一个多列 GiST 索引可以用于条件中涉及到任意索引列子集的查询。在其余列上的条件将限制由索引返回的项,但是第一列上的条件是决定索引上扫描量的最重要因素。当第一列中具有很少的可区分值时,一个 GiST 索引将会相对比较低效,即便在其他列上有很多可区分值。

一个多列 GIN 索引可以用于条件中涉及到任意索引列子集的查询。与 B-tree 或 GiST 不同,GIN 的搜索效率与查询条件中使用哪些索引列无关。

多列 BRIN 索引可以被用于涉及该索引被索引列的任意子集的查询条件。和 GIN 相似且不同于 B-tree 或者 GiST,索引搜索效率与查询条件使用哪个索引列无关。在单个表上使用多个 BRIN 索引来取代一个多列 BRIN 索引的唯一原因是为了使用不同的pages_per_range存储参数。

当然,要使索引起作用,查询条件中的列必须要使用适合于索引类型的操作符,使用其他操作符的子句将不会被考虑使用索引。

多列索引应该较少地使用。在绝大多数情况下,单列索引就足够了且能节约空间和时间。具有超过三个列的索引不太有用,除非该表的使用是极端程式化的。第 11.5 节以及第 11.9 节中有对不同索引配置优点的讨论。