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

相关推荐
JanelSirry2 小时前
真实场景:防止缓存穿透 —— 使用 Redisson 布隆过滤器
数据库·mysql·缓存·redisson·布隆过滤器
mmm.c2 小时前
mysql启动提示1067:进程意外终止
数据库·mysql
一叶飘零_sweeeet3 小时前
MySQL 锁详解
mysql·innodb
沐伊~3 小时前
mysql 安装
数据库·mysql
成为你的宁宁3 小时前
Ubuntu安装mysql5.7及常见错误问题
linux·mysql·ubuntu
努力学习的小廉4 小时前
初识MYSQL —— 复合查询
android·数据库·mysql
熙客15 小时前
Kubernetes是如何保证有状态应用数据安全和快速恢复的
mysql·云原生·容器·kubernetes
倔强的石头10616 小时前
KingbaseES:从兼容到超越,详解超越MySQL的权限隔离与安全增强
数据库·mysql·安全·金仓数据库
小鸡毛程序员17 小时前
我在CSDN学MYSQL之----数据库基本概念和基本知识(下)
数据库·mysql
米花町的小侦探17 小时前
解决 GORM + MySQL 5.7 报错:Error 1067: Invalid default value for ‘updated_at‘
mysql