×

MySQL 慢查询优化实战:从 EXPLAIN 到索引重构的进阶方法

hqy hqy 发表于2026-04-22 17:07:02 浏览7 评论0

抢沙发发表评论

MySQL 慢查询优化实战:从 EXPLAIN 到索引重构的进阶方法

欢迎来到蓝队云技术小课堂,每天分享一个技术小知识。

 

 

很多线上 MySQL 性能问题,最终都可以归结为“慢查询”。但真正的难点不在于发现慢 SQL,而在于如何精准优化

开启慢查询日志:

SET GLOBAL slow_query_log = 'ON';

SET GLOBAL long_query_time = 1;

建议生产环境设置为 1 秒甚至更低,用于捕捉潜在问题。




拿到一条慢 SQL:

SELECT * FROM orders WHERE user_id = 10001 ORDER BY create_time DESC LIMIT 10;

第一步不是改 SQL,而是分析执行计划:

EXPLAIN SELECT * FROM orders WHERE user_id = 10001 ORDER BY create_time DESC LIMIT 10;

重点关注几个字段:

· type:访问类型(ALL / index / range / ref / const)

· rows:扫描行数

· Extra:是否出现 Using filesortUsing temporary

如果你看到:

type: ALL

Extra: Using filesort

说明发生了全表扫描 + 排序,这是典型性能杀手。




优化思路不是“加索引”,而是加对索引

针对这个 SQL,很多人会这样做:

CREATE INDEX idx_user_id ON orders(user_id);

结果性能依然不好,因为排序字段没有被覆盖。

正确方式是使用联合索引

CREATE INDEX idx_user_time ON orders(user_id, create_time DESC);

这会带来两个关键优化:

· WHERE 条件命中索引

· ORDER BY 利用索引顺序,避免 filesort




再看一个常见坑:

SELECT * FROM orders WHERE DATE(create_time) = '2026-04-01';

这个 SQL 即使有索引也不会生效,因为对字段做了函数操作。

错误写法会导致:

type: ALL

正确优化:

SELECT * FROM orders

WHERE create_time >= '2026-04-01 00:00:00'

  AND create_time <  '2026-04-02 00:00:00';

让索引“可用”,比“存在”更重要。




覆盖索引也是一个关键优化点。

如果原 SQL:

SELECT * FROM orders WHERE user_id = 10001;

可以优化为:

SELECT id, user_id, create_time

FROM orders

WHERE user_id = 10001;

并建立索引:

CREATE INDEX idx_cover ON orders(user_id, create_time);

这样可以实现:

Extra: Using index

即无需回表,性能显著提升。




再看分页优化问题:

SELECT * FROM orders ORDER BY id LIMIT 100000, 10;

这是典型的“深分页”,MySQL 会扫描前 100000 行再丢弃。

优化方式:

SELECT * FROM orders

WHERE id > 100000

ORDER BY id

LIMIT 10;

或者结合子查询:

SELECT * FROM orders

WHERE id >= (

    SELECT id FROM orders ORDER BY id LIMIT 100000, 1

)

LIMIT 10;

避免无意义扫描。




索引不是越多越好,过多索引会带来:

· 写入性能下降

· 索引维护成本高

· 优化器选择错误路径

可以用如下语句查看索引使用情况:

SHOW INDEX FROM orders;

或者结合 performance_schema 分析热点 SQL。




最后一个容易忽略的点是统计信息:

ANALYZE TABLE orders;

当数据分布发生变化时,优化器可能做出错误决策,定期更新统计信息非常重要。




总结实战经验:

· 慢查询优化从 EXPLAIN 开始,而不是“猜”

· 联合索引要匹配 WHERE + ORDER BY

· 避免对索引字段做函数操作

· 覆盖索引是高性能关键手段

· 深分页必须改写 SQL

· 定期更新统计信息,避免优化器误判

MySQL 性能优化的本质,不是“调参数”,而是让数据访问路径尽可能短。谁减少了扫描,谁就赢了。


打赏

本文链接:https://www.kinber.cn/post/6481.html 转载需授权!

分享到:


推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

 您阅读本篇文章共花了: 

群贤毕至

访客