MySQL 慢查询定位与索引优化实战:从慢日志到执行计划

举报
yd_270427807 发表于 2026/11/08 08:24:55 2026/11/08
【摘要】 一、慢查询优化的正确顺序很多人在遇到慢查询时第一反应是"加索引",但加错索引反而会让写入变慢、优化器选错执行计划。正确的顺序是:开启慢日志 → 找出真正慢的 SQL → 看执行计划 → 针对性优化 → 验证效果。跳步往往会事倍功半。二、第一步:让慢查询"无处可藏"开启慢查询日志SET GLOBAL slow_query_log = ON;SET GLOBAL long_query_time ...

一、慢查询优化的正确顺序

很多人在遇到慢查询时第一反应是"加索引",但加错索引反而会让写入变慢、优化器选错执行计划。正确的顺序是:开启慢日志 → 找出真正慢的 SQL → 看执行计划 → 针对性优化 → 验证效果。跳步往往会事倍功半。

二、第一步:让慢查询"无处可藏"

开启慢查询日志

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;          -- 超过 1 秒记录
SET GLOBAL log_queries_not_using_indexes = ON;  -- 记录未走索引的 SQL

生产环境要注意:log_queries_not_using_indexes 在低选择性的小表上会刷出大量日志,建议配合 min_examined_row_limit 限制。

用 performance_schema 看实时热点

SELECT DIGEST_TEXT, COUNT_STAR, AVG_TIMER_WAIT/1000000000 AS avg_ms
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;

这比慢日志更实时,能按"总耗时"排序找出拖垮数据库的 SQL,而不只是单条最慢的。

三、第二步:用 EXPLAIN 读懂执行计划

EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = 'paid' ORDER BY created_at DESC;

重点看这几列:

  • type:从好到差是 system > const > eq_ref > ref > range > index > ALL。ALL 是全表扫描,index 是全索引扫描,都要警惕。
  • key:实际使用的索引。为 NULL 说明没走索引。
  • rows:预估扫描行数。数字越大越可能慢。
  • Extra:Using filesort(额外排序)、Using temporary(临时表)都是性能杀手;Using index 是覆盖索引,最好。

MySQL 8.0 可用 EXPLAIN ANALYZE 看实际耗时,比预估更准。

四、第三步:针对性优化

1. 联合索引遵循"最左前缀"

对于 WHERE user_id = ? AND status = ? ORDER BY created_at DESC,理想索引是 (user_id, status, created_at)。顺序原则:等值条件在前,排序字段在后。这样既能用上索引过滤,又能避免 filesort。

2. 覆盖索引减少回表

如果查询只需要少量列,把查询列也放进索引,形成覆盖索引,Extra 出现 Using index,避免回表查主键再取数据。

3. 避免索引失效的写法

  • 在索引列上做函数运算或表达式:WHERE DATE(created_at) = '2026-11-08' 会让索引失效,改成范围查询 created_at >= ... AND created_at < ...。
  • 隐式类型转换:WHERE phone = 13800138000(phone 是 varchar)会失效,要加引号。
  • 前导模糊匹配:LIKE '%abc' 用不上索引,LIKE 'abc%' 可以。
  • OR 连接的条件若有一侧无索引,整体可能退化为全表扫描。

4. 深分页优化

LIMIT 1000000, 20 会扫描大量行再丢弃。改用"延迟关联"或"游标分页"(记住上一页最后的主键):

SELECT * FROM orders WHERE id > 上次最大id ORDER BY id LIMIT 20;

五、第四步:验证与回归

  • 优化后用 EXPLAIN 确认 type 提升、rows 下降、filesort 消失。
  • 在压测环境用真实数据量验证,小表上的优化结论在大表上可能不成立。
  • 关注写入影响:每加一个索引都会增加写入开销和存储,索引不是越多越好。

六、排查清单

  1. 开启慢日志 + performance_schema 找热点 SQL。
  2. EXPLAIN 看 type/key/rows/Extra。
  3. 按最左前缀设计联合索引,尽量覆盖索引。
  4. 排查函数运算、隐式转换、前导模糊等索引失效写法。
  5. 深分页用游标或延迟关联。
  6. 优化后 EXPLAIN + 压测验证,并评估写入开销。

一句话总结:慢查询优化不是"加索引",而是"先定位、再看计划、后优化、最后验证";索引要按查询模式设计,而不是见慢就加。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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