Postgres 并行使用两个索引用于 WHERE 子句

问题描述 投票:0回答:1

我的表有几十亿行。表中有两列:

match_id uuid,
group_id integer

并且在上述两列上都创建了索引:

create index if not exists my_tbl_match_id_idx on my_tbl (match_id);
create index if not exists my_tbl_group_id_idx on my_tbl (group_id);

当我执行以下查询时,两个索引都会并行扫描。 match_id 索引查找速度要快得多,并会在 13 毫秒内返回结果,而

group_id
索引查找速度较慢,需要 1.3 。因为两个索引都是并行查找的,所以总体查询时间 = 1.3 秒,即 group_id 索引的查找时间。

Postgres 有什么办法可以在计算

group_id
结果集后使用
match_id
索引吗?

SELECT *
FROM my_table
WHERE match_id = 'e089e0af-543b-45d5-abbf-22c6c5ed9a01'
AND (group_id IN (167,1704,1864,2065,2145,3812,3814,3855,7462,11393,11394,11396))

或者我需要为

match_id
group_id
创建复合索引吗?

postgresql indexing database-design postgresql-performance
1个回答
1
投票

影响最佳行动方案的因素有很多,其中大多数因素在问题中并不清楚。请考虑问题的说明这里

一般来说,

(match_id, group_id)
(带有前导
match_id
!)上的多列索引比在位图索引扫描中组合两个单独的索引对于查询来说性能要好得多。

实际上,该索引完全实现了您的要求

Postgres 有什么办法可以在计算

group_id

 结果集后使用 
match_id
 索引吗?

多列索引首先按前导表达式排序。使用此索引 Postgres 会排除

group_id

 上与您的查询不相关的大部分匹配项。应该对您的案例特别有影响,因为 
match_id
 似乎更具选择性。

参见:

  • 什么是“位图索引”?
  • 具有异构数据类型的 3 个字段的多列索引
该索引还涵盖了对

match_id

 的查询,就像您在评论中提到的那样。由于 
match_id
 是更具选择性和更大的列(
uuid
 = 16 字节,int = 4 字节),因此多列索引并不比 
(match_id)
 上的索引大很多,并且对于目的,使得维护第二个索引的开销值得怀疑。 
(group_id)
 上的另一个索引仍可用于仅 
group_id
 上的查询。

参见:

  • 复合索引也适合第一个字段的查询吗?
© www.soinside.com 2019 - 2024. All rights reserved.