订单列表接口线上响应 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 改写 > 架构优化