我的表有几十亿行。表中有两列:
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-性能问题的说明这里。
一般来说,
(match_id, group_id)
(带有前导 match_id
!)上的多列索引比在位图索引扫描中组合两个单独的索引对于查询来说性能要好得多。
实际上,该索引完全实现了您的要求:
Postgres 有什么办法可以在计算多列索引首先按前导表达式排序。使用此索引 Postgres 会排除
group_id
结果集后使用match_id
索引吗?
group_id
上与您的查询不相关的大部分匹配项。应该对您的案例特别有影响,因为
match_id
似乎更具选择性。参见:
该索引还涵盖了对
match_id
的查询,就像您在评论中提到的那样。由于
match_id
是更具选择性和更大的列(
uuid
= 16 字节,int = 4 字节),因此多列索引并不比
(match_id)
上的索引大很多,并且对于目的,使得维护第二个索引的开销值得怀疑。
(group_id)
上的另一个索引仍可用于仅
group_id
上的查询。参见: