mysql执行SQL时如何利用explain分析_mysqlSQL执行分析技巧

6次阅读

explain关键看type、key、rows、extra四列:type差为all(全表扫描),key空表示未用索引,rows是预估扫描行数,extra含using filesort/temporary为性能红灯。

mysql执行SQL时如何利用explain分析_mysqlSQL执行分析技巧

EXPLAIN 输出字段怎么看

执行 EXPLAIN select ... 后,关键要看 typekeyrowsExtra 这四列:

  • type 值从好到差一般是:consteq_ref > ref > range > index > ALL;出现 ALL 说明全表扫描,大概率缺索引
  • key 为空表示没走索引;即使非空,也要结合 key_len 看是否用了联合索引的最左前缀
  • rowsmysql 预估扫描行数,不是结果行数;比实际数据量大很多时,统计信息可能过期,可运行 ANALYZE table
  • Extra 出现 Using filesortUsing temporary 是性能红灯,通常意味着排序或分组没走索引

哪些 SQL 必须加 EXPLAIN

不是所有语句都值得分析,优先盯住这几类:

  • 响应明显变慢的线上查询(尤其是 SELECTORDER BY / GROUP BY / 多表 JOIN
  • 写入频繁但查询也多的表上的 WHERE 条件,比如 WHERE status = ? AND created_at > ?
  • 任何在慢日志里出现的语句(slow_query_log 开启后抓出来的)
  • 用到了函数或计算的条件,如 WHERE YEAR(create_time) = 2024 —— 这种几乎必然无法用索引

EXPLAIN 的常见误判和陷阱

EXPLAIN 只是预估执行计划,不真正执行 SQL,所以有几处容易误导:

  • 不会反映实际锁等待、MVCC 版本链遍历开销,高并发rows=100 的语句可能卡住几秒
  • IN 子查询支持有限,EXPLAIN 可能显示 DEPENDENT SUBQUERY 却不告诉你子查询被反复执行多少次
  • MySQL 8.0+ 引入了 forMAT=json 模式(EXPLAIN format=JSON SELECT ...),能看更细的 cost_infoused_columns,但默认文本模式看不到
  • 如果语句含用户变量(如 @var := @var + 1),EXPLAIN 会直接报错或返回空,得先剥离逻辑再分析

配合 SHOW PROFILE 定位真实瓶颈

EXPLAIN 告诉你“怎么走”,但不告诉你“哪一步最耗时”。开启 profiling 后可补全这一环:

  • 先执行 SET profiling = 1
  • 再跑你的 SQL
  • 然后查 SHOW PROFILES 找 query_id,再用 SHOW PROFILE FOR QUERY N 看各阶段耗时(如 Sending data 高说明结果集大或网络慢,Creating sort index 高说明排序没走索引)
  • 注意:profiling 在 MySQL 8.0 中已被标记为 deprecated,生产环境建议用 performance_schema 替代,但开发调试仍够用

实际调优时,EXPLAIN 只是起点。真正难的是判断「为什么没走索引」——是隐式类型转换?是索引失效于范围查询后的字段?还是优化器基于错误统计选了次优路径?这些往往要结合 SHOW CREATE TABLESHOW INDEX 和真实数据分布一起看。

text=ZqhQzanResources