MySQL 慢查询优化实战:看懂执行计划,性能提升 10 倍不是梦。

这次分享,是我在项目中亲身经历的一个"接口变慢"的真实案例。

有一天业务方突然反馈,说有个订单查询接口"变得很慢",用户点一下,几秒钟才出数据。起初我们以为是 Redis 缓存没命中,或者服务器资源吃满了,结果查了一圈,问题出在------SQL执行计划选错索引了。

这次优化经历很有意思,也很有代表性,我想整理下来分享给大家。


1️⃣ 线上接口为什么慢?

我们的问题出在一个分页查询接口,SQL 大致如下:

ruby 复制代码
SELECT * FROM t_orderWHERE status = ?AND create_time BETWEEN ? AND ?ORDER BY create_time DESCLIMIT ?, ?;

表里大概 500 万条数据,字段都有索引,怎么看都挺"正常"。

但是:

  • 本地开发环境执行只需 50ms;
  • 上线生产后,执行时间飙升到 3.6 秒
  • 分页越靠后越慢,甚至会超时。

这就不正常了。


2️⃣ EXPLAIN 看执行计划,问题找到了

通过 EXPLAIN 一查,执行计划如下:

  • type: range
  • key: create_time
  • rows: 4500000
  • Extra: Using where; Using filesort

看到这我就懵了:为啥用了 create_time 的索引,而不是 status + create_time 的组合索引?

这意味着:MySQL 扫描的数据太多,效率极低。


3️⃣ 如何优化?

我们分析之后做了两点调整:

加组合索引:

sql 复制代码
ALTER TABLE t_order ADD INDEX idx_status_time (status, create_time);

这样能让 MySQL 直接定位到符合 status 的数据段,再通过 create_time 快速定位,提高效率。

避免深度分页:

Limit 页码越大,MySQL 需要跳过更多记录。可以考虑:

  • 改用 游标分页(基于 create_time + id 作为下一页起点);
  • 热门页做缓存,比如第一页用 Redis 缓存起来。

4️⃣ 优化效果

我们做完索引调整后,对比数据如下:

分页位置 优化前耗时 优化后耗时
第 1 页 300ms 50ms
第 100 页 3.6s 200ms

效果非常明显,性能提升 10 倍以上。


5️⃣ 小结:关于慢 SQL 的常见坑

  • ✅ 模糊查询 like '%xxx',容易导致索引失效;
  • ✅ where 里使用函数(如 DATE(create_time)),也会失效;
  • ✅ 多字段组合索引,顺序不对等于没用;
  • ✅ limit 深分页,慎用;
  • ✅ select * 查询大字段,响应也会慢。

写在最后

这次慢 SQL 优化的过程,其实也让我更加理解了一件事:

工具不难,关键在于理解背后的机制。

MySQL 到底用了哪个索引?为什么用了这个索引?这些都是我们必须掌握的技能点。

如果你也遇到过类似问题,欢迎留言聊聊,我们一起进步 👇

📌 后续我还会分享更多数据库相关实战经验:索引设计、锁机制、事务问题、慢日志分析......

欢迎关注「Debug笔记」,咱们下篇见~

相关推荐
qq_283720054 小时前
MySQL技巧(九): Binlog 完整格式解析(ROW 模式,默认)
mysql·binlog·数据恢复
Java面试题总结5 小时前
MySQL篇 索引失效
数据库·mysql
last demo5 小时前
mysql
运维·数据库·mysql·oracle
花间相见8 小时前
【MySQL面试题】—— MySQL面试高频问题汇总:从原理到实战,覆盖90%考点
数据库·mysql·面试
qq_3660862210 小时前
sql server OUTER APPLY使用
数据库·sql·mysql
zzh08110 小时前
Mysql数据库备份与恢复笔记
数据库·笔记·mysql
dgvri10 小时前
Linux(CentOS)安装 MySQL
linux·mysql·centos
zjjsctcdl11 小时前
java与mysql连接 使用mysql-connector-java连接msql
java·开发语言·mysql
洛菡夕11 小时前
MySQL全量、增量备份与恢复
数据库·mysql
九皇叔叔11 小时前
深度拆解MySQL InnoDB存储引擎架构:从内存到磁盘的全链路解析
mysql·innodb·存储引擎