MySQL执行计划(EXPLAIN)

 

一、执行计划的核心价值

  • 是什么: MySQL优化器为给定SQL语句生成的具体执行方案。它展示了查询的执行顺序、索引使用情况、预计扫描行数等关键信息。

  • 为什么重要: 是进行科学SQL优化的基石。摒弃“凭感觉”优化,通过分析执行计划,可以精准定位性能瓶颈(如全表扫描、未使用索引、临时表排序等)。

二、如何获取执行计划

在SQL语句前加上 EXPLAINEXPLAIN FORMAT=JSON(获取更详细信息)即可。

EXPLAIN SELECT * FROM users WHERE name = '小明';

三、执行计划关键字段详解(按重要性排序)

1. type(访问类型)—— 最核心指标

此列表示MySQL决定如何查找表中的行。从最优到最差排序如下

  • system > const > eq_ref > ref > range > index > ALL

类型 含义与场景 性能评价
system 表只有一行(如系统表)。是const的特例。 最优
const 通过主键唯一索引等值查询,最多返回一行。SELECT * FROM user WHERE id = 1; 极优
eq_ref 在联表查询(JOIN)中,使用主键唯一索引进行关联匹配,每行只匹配一条记录 非常优
ref 使用普通索引进行等值查询,可能返回多行SELECT * FROM user WHERE name = ‘小明’;
range 范围扫描索引。常见于BETWEEN><IN()等操作。 良好
index 全索引扫描。遍历整个索引树(比全表扫描快,因为索引文件通常更小)。常见于覆盖索引查询。 较差
ALL 全表扫描。没有使用索引,需要遍历所有行。 最差(需重点优化)

优化目标: 在SQL优化中,应尽量避免ALLindex,尽可能让type达到range及以上级别。

2. keypossible_keys

  • possible_keys 可能用到的索引。列出查询中涉及字段上所有存在的索引

  • key 实际使用的索引。如果为NULL,则表示未使用索引。

  • 优化洞察: 如果possible_keys有值而keyNULL,说明索引可能因为数据类型不匹配、函数操作等原因失效,需要检查SQL写法。

3. rows(预估扫描行数)

  • 含义: MySQL优化器预估为了找到所需记录,需要扫描的行数。

  • 核心作用: 最直观的效率指标。对比同一查询的不同写法或索引设计,rows值越小的执行计划通常越优。

4. Extra(额外信息)—— 重要优化提示

此列包含关于MySQL如何解析查询的额外信息,是发现潜在问题的关键。

常见值 含义与影响 优化建议
Using index 使用了覆盖索引。查询的列都包含在索引中,无需回表,性能极佳。 积极追求,通过创建合适的联合索引实现。
Using where 服务器在存储引擎检索行后,使用WHERE条件进行过滤。如果typeALLindex,则意味着大量数据被扫描后丢弃,效率低。 尝试为WHERE条件中的字段建立有效索引。
Using filesort 额外的一次排序。MySQL无法利用索引顺序完成排序,需要在内存或磁盘中进行排序操作。性能杀手 考虑为ORDER BY子句建立索引。
Using temporary 使用了临时表来保存中间结果。常见于GROUP BYDISTINCTUNION等操作。性能杀手 优化查询结构或为GROUP BY字段建立索引。
Using join buffer 使用了连接缓冲区。常见于多表关联且未走索引时。 检查关联字段是否有索引。

5. 其他辅助字段

  • id 查询序列号。id越大,执行优先级越高;id相同,按顺序执行。

  • select_type 查询类型(如SIMPLE简单查询、PRIMARY主查询、SUBQUERY子查询等),用于理解复杂查询的结构。

  • table 当前行正在访问的表。

  • key_len 使用的索引的长度(字节数)。对于联合索引,可以用于判断实际命中了索引的哪些部分

  • ref 显示索引的哪一列被使用了。可能是const(常量)、字段名或NULL

  • filtered 表示存储引擎返回的数据在服务器层过滤后,剩余行数的百分比。值越大越好,说明预筛选效率高。

四、SQL优化实战分析流程

  1. 抓取慢SQL: 通过慢查询日志或性能监控工具定位目标SQL。

  2. 使用EXPLAIN: 对慢SQL执行EXPLAIN分析。

  3. 重点关注以下“危险信号”:

    • type 列为 ALLindex

    • key 列为 NULL(未使用索引)。

    • rows 数值异常巨大。

    • Extra 列出现 Using filesortUsing temporary

  4. 针对性优化:

    • 如果未用索引,检查WHEREJOINORDER BYGROUP BY子句中的字段,考虑创建或修改索引。

    • 如果出现文件排序或临时表,尝试通过调整索引或改写SQL来避免。

    • 如果rows过大,考虑是否可以通过更精确的查询条件或索引来减少扫描范围。

  5. 验证优化效果: 优化后再次执行EXPLAIN,对比typekeyrowsExtra等关键指标是否改善。

总结: 掌握EXPLAIN,就是掌握了与MySQL优化器对话的能力。核心是看懂 type 了解数据访问方式,关注 rows 评估扫描成本,警惕 Extra 中的性能警告,并以此为指导进行科学的索引设计和SQL重构。

 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐