MySQL慢查询优化:从3秒到30毫秒的完整实录

发布时间:2026/9/15 6:39:13
MySQL慢查询优化:从3秒到30毫秒的完整实录 上周三凌晨监控告警突然炸了订单列表接口平均响应时间突破3秒P99更是飙到8秒。用户端大量超时客服电话被打爆。我打开慢查询日志一场从3秒到30毫秒的优化战役就此打响。定位慢查询日志揪出元凶先看慢查询日志一条SQL赫然在目sql复制下载SELECT FROM orders WHERE user_id 12345 AND status 1 ORDER BY create_time DESC LIMIT 10;这张订单表有2000万行数据user_id和status各自有单列索引。EXPLAIN结果让人倒吸一口凉气typeALL全表扫描rows19800000Extra里写着Using filesort。MySQL先扫全表再排序最后取10条——3秒已经算快了。第一步联合索引但顺序有讲究直觉告诉我该建联合索引。先试了(user_id, status)结果typeref但Using filesort依然存在。因为排序字段create_time不在索引里MySQL仍需额外排序。调整为(user_id, status, create_time)后Extra终于变成了Using where; Using index condition排序消失了。响应时间从3秒降到500毫秒。但离30毫秒还差得远。第二步消除回表覆盖索引立功问题出在SELECT。虽然索引命中了但查询需要所有字段MySQL必须拿着主键ID回表查完整行。10条数据就要回表10次如果数据分散在不同页随机IO开销巨大。我改成先查主键再关联取详情sql复制下载SELECT o. FROM orders o INNER JOIN ( SELECT id FROM orders WHERE user_id 12345 AND status 1 ORDER BY create_time DESC LIMIT 10 ) t ON o.id t.id;子查询用上了覆盖索引(user_id, status, create_time, id)不需要回表外层只用10次主键查询。响应时间骤降到80毫秒。第三步细节打磨压榨最后50毫秒80毫秒已经不错但距离30毫秒还有差距。继续排查统计信息过期。ANALYZE TABLE orders更新统计信息后优化器选择了更优的执行计划。缓冲池命中率。检查innodb_buffer_pool_size发现只有2GB而热数据就有8GB。调整为12GB后磁盘IO大幅减少。分页优化。这个接口其实还有翻页逻辑深分页时LIMIT 100000, 10会扫描大量无用行。改用游标分页基于create_time和id做条件过滤。连接池调优。HikariCP的maxPoolSize从20调到50避免高并发下连接等待。一轮组合拳下来再次压测平均响应时间稳定在30毫秒P99控制在50毫秒以内。从3秒到30毫秒整整提速100倍。复盘慢查询优化的四个原则索引不是越多越好顺序决定成败。联合索引要兼顾过滤和排序把等值查询字段放前面范围或排序字段放后面。警惕SELECT。它让覆盖索引失效强制回表。只取需要的列或者用延迟关联。统计信息和缓冲池是隐形杀手。优化器依赖统计信息选执行计划缓冲池大小决定磁盘IO次数。这两项配置不当再好的索引也白搭。深分页必须用游标。LIMIT offset, size在offset大时性能断崖式下跌游标分页才是正解。优化不是一次性的上线后我设置了慢查询阈值200毫秒每天自动推送Top 10慢SQL。毕竟30毫秒的成绩需要持续守护。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询