mysql如何查看执行计划_mysqlexplain命令解析

6次阅读

explain用于查看select语句的执行计划,不实际执行(子查询除外);type字段最关键,all最差,理想为range及以上;key与possible_keys不一致需查索引选择性、统计信息或联合索引顺序;extra中using filesort和using temporary共存预示性能严重问题。

mysql如何查看执行计划_mysqlexplain命令解析

直接在 SELECT 前加 EXPLAIN 就能看到执行计划

mysql 不需要额外安装或开启配置,只要你的查询是 SELECT,在它前面加上 EXPLAIN 关键字,立刻返回执行计划的结构化信息。这不是日志、不是慢查分析,而是优化器“打算怎么执行”的快照——注意,它不真正执行语句(除非 FROM 里有子查询,那部分会被实际执行并写入临时表)。

  • 正确写法:EXPLAIN SELECT * FROM user WHERE id = 123;
  • 错误写法:EXPLAIN UPdate ...EXPLAIN INSERT ... —— 这些会报语法错误,EXPLAIN 只支持 SELECT(及 delete/INSERT/REPLACE 的某些变体,但生产中几乎不用,别依赖)
  • 别用 EXPLAIN format=json 初学:虽然更详细,但字段嵌套深、可读性差,先盯住默认表格输出的 10 列,比 JSON 更快定位问题

type 字段决定查询快不快,优先看它是不是 ALLindex

type 是执行计划里最敏感的性能信号灯。它告诉你 MySQL 怎么“找数据”:是从整张表扫(ALL),还是走索引跳(refeq_ref),或是只查一行(const)。从差到好排序是:ALLindexrangerefeq_refconst

  • type=ALL:全表扫描,意味着没走索引,或者 WHERE 条件用了函数/隐式转换(比如 WHERE DATE(create_time) = '2025-01-01'),哪怕字段上有索引也废了
  • type=index:比 ALL 稍好,但仍是遍历整个索引树,常见于 SELECT count(*) FROM t(无 WHERE)或只查索引覆盖字段但没加 WHERE 条件
  • 目标至少是 range:说明用了索引做范围查找(>=BETWEENIN),再往上 ref(等值查非唯一索引)和 eq_ref(主键/唯一索引关联)才是健康状态

keypossible_keys 对不上?说明优化器放弃了你建的索引

possible_keys 是“候选索引列表”,key 是“最终选中的那个”。两者不一致很常见,但值得深挖原因:

  • 索引选择性太低:比如给性别字段(只有 ‘M’/’F’)建了索引,优化器发现走索引还不如全表扫描快,就弃用
  • 统计信息过期:ANALYZE table t; 强制刷新行数、索引分布等元数据,有时能“唤醒”被忽略的索引
  • WHERE 条件顺序和联合索引顺序不匹配:比如索引是 (a,b,c),但查询写了 WHERE b = 1 AND c = 2a 没出现,这个索引就无法使用前缀匹配,key 会是 NULL
  • 别盲目加索引:possible_keys 里出现多个索引,反而可能说明表设计或查询逻辑有问题(比如字段冗余、条件拆分不当)

别漏看 Extra 里的隐藏开销

Extra 是执行计划的“备注栏”,里面藏着真实性能杀手:

  • Using filesort:MySQL 要额外排序,通常因为 ORDER BY 字段没走索引,或排序字段和 WHERE 字段不在同一索引里
  • Using temporary:创建了临时表,常见于 GROUP BY + ORDER BY 字段不一致、或子查询结果需缓存
  • Using index(注意没有 filesorttemporary):这是好消息,表示走了“覆盖索引”,不用回表查数据行
  • Using where:正常现象,说明 MySQL 在存储引擎层之后又做了一次过滤(比如索引只能过滤部分条件,剩余条件靠 Server 层判断)

真正容易被忽略的是:Using filesortUsing temporary 同时出现,往往意味着查询已脱离可控范围——这时光调索引没用,得重审业务逻辑是否允许分页改写、聚合下推或结果集裁剪。

text=ZqhQzanResources