如何让 Postgres 对一组值使用索引?

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

我有一个大约 35M 行的表,并尝试查找“已处理”记录以不时删除。有效状态有 14 个,已处理 10 个。

id uuid default uuid_generate_v4() not null primary key,
fk_id uuid not null references fk_table,
-- ... other columns
created_date timestamptz default now() not null,
status varchar(128) not null

索引在

(status,created_date)

像这样的查询:

select id from table
where created_date < 'somedate'
and status = ANY('{a,b,c..10}')

查询规划器坚持使用完整的 seq_scan,而不是索引。

有什么技巧可以让 Postgres 使用谓词的

status = ANY
部分的索引吗?

postgresql indexing sql-execution-plan postgresql-performance postgres-12
1个回答
0
投票

如果超过百分之几的行符合条件 - 或者更确切地说,如果 Postgres 估计 一样多 - 它将选择顺序扫描,对于这种情况,这会更快。

如果事实上只有少数行符合条件,那么您的列统计信息(和/或成本设置)应该归咎于误导性的估计。

如果引用的索引仅用于手头的目的,并且只有相对较少的行具有“已处理”状态,请将其替换为部分索引

CREATE INDEX foo ON tbl (created_date) WHERE status = ANY('{a,b,c..10}')

将使索引更小,查询更快,并且使用它的可能性更大。

无论哪种方式,至少增加一点

created_date
和状态的统计目标很可能是有帮助的。参见:

无论哪种方式,仅对于“14个有效状态”

status varchar(128)
似乎非常浪费。

更多取决于缺失的细节......

© www.soinside.com 2019 - 2024. All rights reserved.