PostgreSQL部分索引疑问:更新前后索引字段均为NULL是否会触碰索引?
问题结论
不会触发该部分索引的任何改动。
原理说明
- PostgreSQL 部分索引只会存储满足创建时指定的
WHERE谓词条件的行,你创建的是仅包含索引字段非NULL值的索引,更新前后索引字段均为NULL的行,从始至终都不满足索引的准入条件,自然不会涉及任何索引的增删改操作,也不会产生对应的锁、IO开销。
适配你的使用场景
你要实现的需求可以通过以下方案完美落地,完全不会影响日常高吞吐更新:
- 首先创建对应部分索引,语句参考:
CREATE INDEX idx_<你的表名>_deleted_nonnull ON <你的表名> (deleted) WHERE deleted IS NOT NULL;
- 你的日常更新操作仅针对
deleted = NULL的活跃行,这些行全程不在上述索引的覆盖范围内,不会产生任何该索引的额外更新、锁开销,完全符合你的预期。 - 该索引仅会在两类低频次操作时产生开销:
- 执行软删除将
deleted从NULL设为非NULL值时,会将对应行加入索引 - 执行硬删除操作时,会将对应行从索引中移除
- 执行软删除将
- 硬删除一周前软删数据的查询语句参考,该语句可以直接命中上述部分索引,不需要全表扫描,执行效率极高:
DELETE FROM <你的表名> WHERE deleted < NOW() - INTERVAL '1 week';
内容的提问来源于stack exchange,提问作者Avihai Berkovitz
相关产品推荐
相关产品推荐

