mysql执行SQL时如何分析慢查询_SQL执行性能排查思路

5次阅读

需先开启慢查询日志(slow_query_log=on)、设阈值(long_query_time=0.5~1)、指定路径,并关闭log_queries_not_using_indexes;再用explain分析type、key、rows、extra四列,重点关注全表扫描、索引失效、文件排序及临时表问题。

mysql执行SQL时如何分析慢查询_SQL执行性能排查思路

怎么定位慢查询sql

mysql默认不记录慢查询,得先打开慢查询日志开关,并设好阈值。否则你根本不知道哪条SQL拖慢了整体响应。

关键配置项:slow_query_log(设为ON)、long_query_time(比如设成1秒)、slow_query_log_file(指定日志路径)。注意:MySQL 5.7+ 默认只记录没走索引的查询,需额外设log_queries_not_using_indexes=OFF避免干扰。

  • 线上建议long_query_time设为0.51,太低会导致日志爆炸
  • 日志文件权限要让MySQL进程可写,否则开启失败但无明显报错
  • SHOW VARIABLES LIKE 'slow_query_log%'确认是否生效,别只改配置不重启/重载

EXPLAIN看执行计划时重点盯什么

EXPLAIN输出里真正影响性能的是typekeyrowsExtra这四列,其他字段多数是辅助信息。

  • type:从好到坏是consteq_ref > ref > range > index > ALL;出现ALL基本等于全表扫描
  • key为空说明没走索引,得查WHERE条件字段有没有对应索引,或索引是否被隐式转换失效(比如对varchar字段用数字查询)
  • rows是MySQL预估扫描行数,如果远大于实际结果集,说明统计信息过期,可运行ANALYZE table更新
  • Extra里出现Using filesortUsing temporary要警惕,尤其是二者同时出现,大概率需要优化排序或关联方式

ORDER BY和GROUP BY为什么容易慢

这两个操作若无法利用索引完成,MySQL会强制使用临时表+文件排序,I/O和内存开销陡增。

例如select * FROM orders WHERE status = 1 ORDER BY create_time DESC,即使status有索引,create_time没包含在索引里,就无法避免Using filesort

  • 复合索引顺序很重要:WHERE条件字段在前,ORDER BY字段紧随其后,比如(status, create_time)
  • GROUP BY同理,优先复用WHERE索引,再追加分组字段;如果带聚合函数又没索引,可能触发Using temporary
  • 避免SELECT * + ORDER BY,只查必要字段能减少排序数据量

JOIN太多或字段类型不一致导致隐式转换

多表JOIN本身不必然慢,但一旦驱动表选错、连接字段类型不匹配,就会让索引完全失效。

典型例子:user.idBIGINTorder.user_idVARCHAR,哪怕加了索引,MySQL也会把user.id转成字符串去比对——索引失效,变全表扫描。

  • SHOW CREATE TABLE确认关联字段类型、长度、字符集是否严格一致
  • 小表驱动大表原则依然有效,但5.7+优化器会自动判断,不过复杂JOIN下仍建议用STRAIGHT_JOIN强制顺序
  • 超过3张表JOIN要考虑是否真有必要,很多时候应用层拆成2次查询反而更快、更可控

慢查询排查不是单点动作,而是“日志抓取 → EXPLAIN验证 → 索引调整 → 再压测”的闭环。最容易被忽略的是统计信息过期和字符集隐式转换——它们不会报错,但会让所有索引形同虚设。

text=ZqhQzanResources