PostgreSQL 14.7部分索引创建:过滤列非空占比高能否提速?
问题描述
我在Postgres 14.7中有如下表:
create table product ( id uuid, description varchar, created_at timestamptz, primary key (id) ); create index idx__product__created_at on product(created_at);
该表有数亿条记录,为简化描述省略了更多列。现在我想执行以下变更:
alter table product add column published_to_kafka timestamptz default null; create index idx__product_published_to_kafka on product (created_at asc) where published_to_kafka is null;
我无法承受数据库出现性能问题,哪怕是短时间的,因此担心该索引创建操作会拖慢数据库。
核心问题:当执行索引创建命令时,若数据库中大部分记录的published_to_kafka列值不为null,是否会提升索引创建的性能?
回答
是的,这种情况会明显提升索引创建的性能,原因如下:
- 部分索引仅处理符合条件的数据:你创建的是部分索引(带
WHERE过滤条件的索引),Postgres只会为满足published_to_kafka is null的记录生成索引条目。如果大部分记录不满足这个条件,需要处理的数据量会大幅减少——比如90%的记录字段值不为null,那索引只需处理剩下10%的数据,IO和CPU开销会成比例降低。 - 复用现有索引减少扫描范围:表上已存在
idx__product__created_at索引,Postgres创建新索引时可以直接扫描这个现有索引,而非全表扫描。现有索引已按created_at排序,Postgres只需遍历索引条目,检查对应published_to_kafka值是否为null,符合条件的就加入新索引,这种方式比全表扫描高效得多。 - Postgres 14并行优化更高效:Postgres 14默认支持并行创建索引,需要处理的数据量越少,并行处理的效率越高,能进一步缩短索引创建时间,减少对数据库资源的占用时长。
另外给两个实用建议,进一步降低对业务的影响:
- 添加
CONCURRENTLY选项创建索引:普通索引创建会持有表的排他锁,阻塞写操作;使用该选项不会锁表,虽然创建时长略长,但能避免业务中断。注意使用该选项时,不能有其他并行的DDL操作。 - 监控系统资源:创建索引期间实时监控CPU、磁盘IO和内存的使用情况,确保资源占用在业务可接受范围内。
内容的提问来源于stack exchange,提问作者AmsterdamLuis
相关产品推荐
相关产品推荐

