数据库慢了,别急着加索引。按这个流程走一遍,能少走很多弯路。
第一步:先确认慢在哪 打开慢查询日志,或者用 pg_stat_statements(PostgreSQL)、performance_schema(MySQL)这类工具,把耗时 Top N 的查询列出来。凭感觉猜是没用的,数据会告诉你真正的热点——往往不是你以为的那条。
第二步:看执行计划 EXPLAIN ANALYZE 跑一遍(注意 ANALYZE 会真的执行,别在生产的 DELETE/UPDATE 上直接跑)。重点看三处:
- 有没有全表扫描(Seq Scan / ALL),大表上的全表扫描是首要嫌疑。
- 估算行数和实际行数差多少。差一个数量级以上说明统计信息过期或者优化器误判。
- 哪一步耗时占比最大。
第三步:检查索引是否真的被用上 常见失效原因:
- 在索引列上套了函数或做了运算。
- 隐式类型转换(比如字符串列用数字查)。
- 联合索引没遵守最左前缀。
- 用了 OR 连接不同列的条件。
- 返回行数占比太高,优化器判断走全表更快。
第四步:改查询本身 很多时候问题不在索引:
- 只查需要的列,别 SELECT *。
- 大偏移量的分页改用游标(记录上一页最后一条的 ID)。
- 子查询改 JOIN,或者反过来,看哪个执行计划更优。
- 能用批量就别循环单条。
第五步:考虑加索引 确认是索引缺失再动手。注意联合索引的列顺序:等值条件在前、范围条件在后。另外别盲目加,每个索引都会拖慢写入并占空间。
第六步:验证 改完再跑一次 EXPLAIN ANALYZE,对比前后耗时。并且要在数据量接近生产的库上验,测试库几百行数据是看不出问题的。
两个容易被忽略的点
- 统计信息。长期大批量导入导出后统计信息会失真,导致优化器选错计划。定期 ANALYZE,必要时调采样精度。
- 连接数。有时候慢不是查询慢,是连接池打满了在排队。先看连接数和锁等待再往下查。
我的判断:优化的顺序永远是「先测量、再改」。没跑 EXPLAIN 就加索引,本质上是在碰运气,而且碰完也不知道成没成。
本文由奇幻维度内容助手整理发布,欢迎在评论区交流你的看法。