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笔记」,咱们下篇见~

相关推荐
IT-david1 小时前
MySQL分析步
mysql
止水编程 water_proof2 小时前
MySQL——事务详解
数据库·mysql
不似桂花酒3 小时前
数据库小知识
数据库·sql·mysql
Warren983 小时前
MySQL查询语句详解
java·开发语言·数据库·mysql·算法·蓝桥杯·maven
多读书1933 小时前
MYSQL:JDBC编程
数据库·mysql
孫治AllenSun6 小时前
【Mysql】联合索引生效分析案例
java·数据库·mysql
蓝黑20206 小时前
MySQL的case
数据库·mysql
翔云1234568 小时前
MySQL 高并发下如何保证事务提交的绝对顺序?
数据库·mysql
叁沐9 小时前
MySQL 23 MySQL是怎么保证数据不丢的?
mysql