⚙️ 后端开发
2026年7月6日2 分钟阅读956从一个慢查询开始,重新理解 PostgreSQL 索引
一次真实的慢查询排查:从 EXPLAIN ANALYZE 到组合索引设计,重新理解 PostgreSQL 索引的工作方式。
后台文章列表页突然变慢,EXPLAIN ANALYZE 走了一遍,顺便把索引的知识重新梳理了一遍。
现场还原
文章列表页按状态过滤再按时间排序:
EXPLAIN ANALYZE SELECT * FROM articles WHERE status = 'PUBLISHED' ORDER BY published_at DESC LIMIT 20;
执行计划显示全表扫描 + 显式排序,耗时 80ms。数据量不算大,但这个计划明显不对劲。
问题出在哪
status 是低基数字段,只有三个值,单独建索引意义不大——优化器会正确地忽略它。真正有效的组合索引是:
CREATE INDEX idx_articles_status_published ON articles (status, published_at DESC);
等值条件在前、排序字段在后,这样索引本身就按 published_at 有序,排序步骤直接消失。加完之后 80ms 变成 0.3ms。
几个加深理解的点
- 索引不是越多越好。每个索引都是写入时的额外负担,博客这种读多写少的场景可以奢侈一点,高频写入的表要克制。
- EXPLAIN 要带 ANALYZE。不看真实执行时间和行数,很容易被估算行数骗。
- 注意最左前缀。
(status, published_at)的索引对只按published_at过滤的查询帮助有限。
小结
慢查询不可怕,可怕的是"加个索引试试"的玄学调优。先看执行计划,理解优化器为什么这么选,再动手。
分享这篇文章
评论