慢 SQL 优化实践
订单列表接口线上响应 3 秒,用户投诉不断。本文还原从发现到优化的全过程。
一、问题发现
- 1.1 监控告警——接口 RT P99 超 3 秒
- 1.2 慢查询日志——
long_query_time = 1s - 1.3 定位到具体 SQL
二、分析阶段
- 2.1 EXPLAIN 执行计划——type=ALL,全表扫描
- 2.2 表数据量——订单表 500 万行
- 2.3 当前的索引情况
三、优化 1:添加索引
- 3.1 创建
idx_user_status_time(user_id, status, create_time) - 3.2 EXPLAIN 对比——type=ref,rows 从 500 万降到 200
- 3.3 效果——RT 从 3s 降到 800ms
四、优化 2:覆盖索引
- 4.1 分析 SELECT 字段——只需要 id, order_no, amount, create_time
- 4.2 创建覆盖索引——
idx_user_status_time_cover(user_id, status, create_time, order_no, amount) - 4.3 Extra: Using index——不需要回表
- 4.4 效果——RT 从 800ms 降到 200ms
五、优化 3:SQL 改写
- 5.1 原来的 SQL——子查询
- 5.2 改写为 JOIN
- 5.3 效果——RT 从 200ms 降到 100ms
六、优化 4:分页优化
- 6.1
LIMIT 100000, 20——越往后越慢 - 6.2 游标分页——
WHERE id > last_id LIMIT 20 - 6.3 效果——RT 稳定在 50ms
七、优化前后对比
- 7.1 响应时间——3s → 50ms(60 倍提升)
- 7.2 扫描行数——500 万 → 20
- 7.3 CPU 使用率明显下降
八、总结
- 慢 SQL 优化的标准流程
- 索引优化 > SQL 改写 > 架构优化
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 谜思录!