首页/数据/SQL 速查/PostgreSQL 部分索引
性能与执行计划72 条

PostgreSQL 部分索引

只索引满足条件的数据行:过滤条件固定、热点数据占比低的查询(如未完成订单)能显著缩小索引。

SQL 速查数据更新于 2026-10-13

只索引一部分数据

PostgreSQL 的部分索引只索引满足条件的那部分行:过滤条件固定、热点数据占比低的查询收益最大,比如只给未完成订单建索引。索引体积更小、维护成本更低,命中前提是查询的过滤条件能被优化器论证出「蕴含索引谓词」。

基本信息

适用平台PostgreSQL
语法CREATE INDEX 名 ON 表 (列) WHERE 谓词
原理索引只覆盖满足谓词的行,体积小、维护成本低
命中前提查询谓词能被论证蕴含索引谓词
典型场景未完成、未删除、指定类型的数据子集

典型使用场景

  • 只给未完成订单建索引,跳过海量已完成数据
  • 逻辑删除场景只索引未删除行
  • 按类型区分的热点子集
  • 降低宽表上索引的体积与写成本
  • 替代对全表一刀切建索引的粗放做法

示例

示例
-- 只给待处理订单建索引
CREATE INDEX idx_orders_pending_created
  ON orders (created_at)
  WHERE status = 'pending';

-- 命中:查询条件包含 status = 'pending'
SELECT * FROM orders
WHERE status = 'pending' AND created_at > now() - interval '1 day';

-- 不命中:查询里没有 status = 'pending' 这个条件
SELECT * FROM orders WHERE created_at > now() - interval '1 day';

命中与不命中

查询写法能否用部分索引原因
带 status = 'pending' 与时间范围可以谓词蕴含索引谓词
只带时间范围不能条件推不出索引谓词
用 IN 列出多个状态视情况需要优化器能论证谓词关系
用不等于某状态通常不能不等条件推不出等价谓词
查询谓词更宽松不能索引覆盖范围更窄
部分索引的价值来自「谓词能被推导」:查询端少写那个条件索引就完全用不上,排查慢查询时先看查询谓词与索引谓词是否对得上。
为状态频繁变化的数据建部分索引要谨慎:行在谓词内外进进出出,索引与统计都要跟着维护,写入成本未必划算。

易错点

  • 查询端少写谓词:条件推不出索引谓词时完全用不上,需要改写查询或调整索引谓词
  • 为状态频繁变化的数据建部分索引:行进出谓词范围时索引与统计都要维护,评估更新成本
  • 用不等条件期望命中:这类条件通常推不出等价谓词
  • 把部分索引当分区表用:它只减少索引体积,不减少表数据,大表清理还要靠归档
  • 建完不验证:要用 EXPLAIN 确认查询确实走了部分索引,否则等于白建

数据来源与参考

  • PostgreSQL Documentation · Partial Indexes
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌