PostgreSQL 创建多列索引(多字段索引)

PostgreSQL 可以在表的一个字段或者多个字段上创建索引,也称之为复合索引或者联合索引。

举个例子,一个表包含 3 个字段,可以在其中的 2 个字段上创建多列索引,如下:

create table t(c1 int, c2 int, c3 text);
create index on t(c1,c2);

\d+ t 查看索引信息,如下:

postgres=# \d+ t
                                     Table "public.t"
 Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
 c1     | integer |           |          |         | plain    |              |
 c2     | integer |           |          |         | plain    |              |
 c3     | text    |           |          |         | extended |              |
Indexes:
    "t_c1_c2_idx" btree (c1, c2)
Access method: heap

关于多列索引,以下信息需要注意

  • 目前只有 B-tree, GiST, GIN 和 BRIN 三种类型的索引支持在多个字段上创建索引
  • 多列索引最多支持 32 个列,如果要修改这个限制,需要修改 pg_config_manual.h 源码,然后重新编译
  • 对于多列 B-tree 索引,如果查询条件里的字段是多列索引的子集,需遵循最左前缀原则才能使用索引加速查询。比如索引字段为 (c1,c2,c3),那么适用该索引的查询条件可以是 (c1),(c1,c2),(c1,c2,c3),而对于 (c2),(c2,c3),(c3) 则无法使用该索引加速查询
  • 多列 GiST 索引可以与涉及索引列的任何子集的查询条件一起使用。附加列上的条件限制索引返回的条目,但第一列上的情况是确定需要扫描多少索引的最重要条件。如果 GiST 索引的第一列只有几个不同的值,即使在其他列中有许多不同的值也相对无效
  • 多列 GIN 索引可以与涉及索引列的任何子集的查询条件一起使用。与 B-tree 或 GiST 不同,无论查询条件使用哪个索引列,索引搜索效果都是相同的
  • 多列 BRIN 索引可以与涉及索引列的任何子集的查询条件一起使用。与 GIN、B-tree 或 GiST 不同,无论查询条件使用哪个索引列,索引搜索效果都是相同的。在单个表上使用多个 BRIN 索引而不是一个多列 BRIN 索引的原因是使用不同的 pages_per_range 存储参数
  • 应当谨慎使用多列索引。在大多数情况下,单个列上的索引就足够了,并且节省了空间和时间。超过三列的索引不太可能有帮助

文章评论

0条评论