【MySQL查询优化案例】从慢查询到毫秒响应的实战复盘
在最近的系统优化中,遇到一个典型的 MySQL 慢查询问题:某后台报表页面加载耗时从 5 秒飙升到 20 秒+。通过层层拆解,最终将查询时间压缩到了 200 毫秒以内。今天就用程序员之间对话的方式,还原这个 MySQL查询优化 的完整思路。
🔍 问题现场:什么拖垮了报表?
用户反馈后台的"订单分析报表"越来越慢。排查日志发现核心 SQL 如下:
SELECT customer_id, SUM(amount), COUNT(order_id)
FROM orders
WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY customer_id
ORDER BY SUM(amount) DESC
LIMIT 100;
单表 500 万数据,执行时间 18.2 秒!EXPLAIN 看到致命问题:全表扫描(type=ALL)且 Using filesort。
🛠️ 四步优化实战
✅ 第一步:重拳出击加索引
关键矛盾在 WHERE 的时间范围和 GROUP BY 分组:
ALTER TABLE orders ADD INDEX idx_ctime_customer (create_time, customer_id);
效果立竿见影:扫描行数从 500万 → 89万!但执行时间仍在 5.2 秒,EXPLAIN 显示 Using temporary; Using filesort。
✅ 第二步:干掉临时表和文件排序
GROUP BY customer_id 后还需按金额排序,导致双重计算。调整索引顺序:
ALTER TABLE orders ADD INDEX idx_customer_ctime_amount (customer_id, create_time, amount);
并改写 SQL 避免排序时二次聚合:
SELECT customer_id, total_amount, order_count
FROM (
SELECT customer_id, SUM(amount) AS total_amount,
COUNT(order_id) AS order_count
FROM orders
WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY customer_id
) AS tmp
ORDER BY total_amount DESC
LIMIT 100;
执行时间降至 1.3 秒!临时表和文件排序消失。
✅ 第三步:精准打击时间范围
时间范围跨度大导致索引利用率低。结合业务拆分为按月聚合:
SELECT customer_id, SUM(month_sum) AS total_amount
FROM (
SELECT customer_id, SUM(amount) AS month_sum
FROM orders
WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY customer_id, DATE_FORMAT(create_time, '%Y-%m')
) AS monthly
GROUP BY customer_id
ORDER BY total_amount DESC
LIMIT 100;
扫描行数再降 60%,耗时 0.8 秒!
✅ 第四步:终极武器——覆盖索引
查询只需 customer_id 和 amount 字段:
ALTER TABLE orders ADD INDEX idx_covering (create_time, customer_id, amount);
最终 0.18 秒 完成!EXPLAIN 的 Extra 列出现 Using index 🎉
💡 优化心法总结
- 索引是命门:联合索引顺序要匹配查询顺序(WHERE > GROUP BY > ORDER BY)
- 避免临时表:GROUP BY 和 ORDER BY 冲突时,用子查询解耦
- 拆大查询:对海量数据分段聚合比单次全集更高效
- 覆盖索引YYDS:理想情况让索引扛下所有查询工作
📘 附赠资源:
最新版《2025 Java面试宝典》👉 点击蓝色链接下载
(提取码:9b3g,涵盖数据库调优、并发实战等高频考点)
🎁 彩蛋:技术人的省钱攻略
如果你准备突击面试,面试鸭会员 涵盖各大厂真题解析(含SQL优化题)。通过 面试鸭返利网 下单可 返现25元,戳这里直达优惠 👇

(用省下的钱买杯咖啡☕,继续肝代码不香吗?)
优化启示录:MySQL查询优化 本质是理解数据访问路径。先看执行计划定位瓶颈,再用索引重构+SQL改写组合拳,往往事半功倍。你在 MySQL查询优化 中踩过哪些坑?评论区见 👇


