我把 API 响应时间从 2 秒降到 200 毫秒,只加了一个索引
上周用户反馈页面加载慢,抓了一下接口,发现某个 API 平均响应 2 秒,高峰期甚至 5 秒。排查了一圈,最后只加了一个数据库索引,降到 200 毫秒。 EXPLAIN 一看,type 是 ALL,全表扫描。orders 表 500 万条数据,每次查询都要扫一遍。 为什么联合索引有效 EXPLAIN 一看,type 是 ref,用了索引,但 Extra 里有 Using filesort。因为索引只排了 user_id,created_at 还是乱的,数据库要额外排序。
问题定位
用慢查询日志分析,发现这条 SQL 执行了 1.8 秒:SELECT * FROM orders WHERE user_id = 12345 ORDER BY created_at DESC LIMIT 20;
解决方案
给 user_id 和 created_at 加联合索引:ALTER TABLE orders ADD INDEX idx_user_created (user_id, created_at DESC);
查询条件是 WHERE user_id = ?,排序是 ORDER BY created_at DESC。联合索引让数据库直接定位到 user_id 的数据,再按 created_at 排好序,不需要回表排序。
效果对比
加索引前:全表扫描 + 文件排序,2 秒。 加索引后:索引覆盖,0.2 秒。
踩坑记录
一开始只给 user_id 加了单列索引:ALTER TABLE orders ADD INDEX idx_user_id (user_id);
改成联合索引后,Using filesort 消失,直接索引取数。
另一个坑
索引加完后,写入变慢了。INSERT 从 50ms 变成 200ms。
因为索引需要维护,每次写入要更新索引树。权衡后,这个表读多写少,索引值得。
总结
慢查询先 EXPLAIN,看 type 和 Extra。ALL + filesort 是典型没索引或索引没用对。
联合索引的顺序很重要,WHERE 条件放前面,ORDER BY 放后面。顺序错了,索引只生效一半。