⚙️ 后端开发
2026年7月6日2 分钟阅读956

从一个慢查询开始,重新理解 PostgreSQL 索引

一次真实的慢查询排查:从 EXPLAIN ANALYZE 到组合索引设计,重新理解 PostgreSQL 索引的工作方式。

从一个慢查询开始,重新理解 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。

几个加深理解的点

  1. 索引不是越多越好。每个索引都是写入时的额外负担,博客这种读多写少的场景可以奢侈一点,高频写入的表要克制。
  2. EXPLAIN 要带 ANALYZE。不看真实执行时间和行数,很容易被估算行数骗。
  3. 注意最左前缀。(status, published_at) 的索引对只按 published_at 过滤的查询帮助有限。

小结

慢查询不可怕,可怕的是"加个索引试试"的玄学调优。先看执行计划,理解优化器为什么这么选,再动手。

分享这篇文章

评论

发表评论

评论提交后需经博主审核,审核通过后才会展示。