MySQL 慢查询排查四步法:从慢日志到索引优化

举报
yd_263188715 发表于 2026/10/30 09:02:46 2026/10/30
【摘要】 按慢日志取证、mysqldumpslow 聚合、EXPLAIN 分析、加索引验证四步,系统定位并解决 MySQL 慢查询。

线上接口突然变慢,很多时候根源是一两条 SQL。与其凭感觉加索引,不如按固定步骤把问题找出来、验证掉。

1. 打开慢查询日志,先拿到证据

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
SHOW VARIABLES LIKE 'slow_query_log_file';

把阈值设成 1 秒(或更低)跑一段业务高峰,日志里就会留下真正拖慢系统的语句。云数据库 RDS for MySQL 可以直接在控制台的「慢日志」页面查看和下载,不用登录主机。

2. 用 mysqldumpslow 聚合,找出最值得优化的语句

mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log

-s t 按总耗时排序,-t 10 取前 10 条。优先处理「总耗时最高」的语句,而不是单次最慢的那条:一条 0.5 秒但每分钟执行上千次的 SQL,往往比偶发的 10 秒查询影响更大。

3. 用 EXPLAIN 看执行计划

EXPLAIN SELECT * FROM orders WHERE user_id = 1001 AND status = 'PAID' ORDER BY created_at DESC LIMIT 20;

重点看这几列:

  • type:出现 ALL 表示全表扫描,至少要做到 ref 或 range。
  • key:实际用到的索引,为 NULL 说明没走索引。
  • rows:预估扫描行数,越大越危险。
  • Extra:Using filesort、Using temporary 是常见的性能杀手。

4. 针对性加索引,再验证

上面的例子可以建联合索引,把等值条件放前面、排序字段放最后:

ALTER TABLE orders ADD INDEX idx_user_status_created (user_id, status, created_at);

建完再跑一次 EXPLAIN,确认 type 变成 ref、Extra 里的 filesort 消失,再对比慢日志里该语句的耗时。

几个常见的坑

  • 对索引列做函数或隐式类型转换(如 WHERE DATE(created_at) = ...、字符串列传数字)会让索引失效。
  • LIKE '%abc' 前缀模糊无法走 B+ 树索引。
  • 索引不是越多越好,写多读少的表要控制数量,大表加索引尽量在低峰期,或使用 Online DDL。

按「慢日志取证、聚合排序、EXPLAIN 分析、加索引验证」这四步走,大多数慢查询都能在一小时内定位并解决。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。