MySQL执行计划

MySQL 的 执行计划(Execution Plan) 是优化器根据 SQL 语句生成的查询执行路径的详细说明。通过分析执行计划,可以了解 MySQL 如何处理 SQL 查询(如索引使用情况、表连接顺序等),进而优化查询性能。

1. 获取执行计划

 使用 EXPLAIN 或 EXPLAIN FORMAT=JSON 命令:

explain   select  * from  students  where id=2

 MySQL执行计划_第1张图片

 

EXPLAIN FORMAT=JSON  select  * from  students  where id=2

 MySQL执行计划_第2张图片

 2. 执行计划输出列解析

 EXPLAIN 输出的关键列及其含义:

列名 说明
id 查询的序列号(层级),相同 id 表示同一层级,值越大优先级越高(子查询等)。
select_type 查询类型,如 SIMPLE(简单查询)、PRIMARY(外层查询)、SUBQUERY 等。
table 当前操作的表名或别名。
partitions 匹配的分区(若表有分区)。
type 访问类型(性能关键指标),常见值:ALLindexrangerefeq_refconst
possible_keys 可能使用的索引。
key 实际使用的索引。
key_len 使用的索引长度(字节数)。
ref 与索引比较的列或常量(如 const 或 other_table.column)。
rows 预估扫描的行数(越小越好)。
filtered 查询条件过滤后剩余行的百分比(与 rows 结合使用)。
Extra 额外信息(如 Using whereUsing temporaryUsing filesort 等)。

 3. 关键指标详解

 

type(访问类型)

按性能从优到劣排序:

  • const:通过主键或唯一索引直接找到一行(最优)。

  • eq_ref:联表查询时,使用主键或唯一索引匹配(如 JOIN ... ON a.id = b.id)。

  • ref:使用非唯一索引查找。

  • range:索引范围扫描(如 BETWEENIN> 等)。

  • index:全索引扫描(遍历索引树)。

  • ALL:全表扫描(性能最差,需优化)。

Extra(额外信息)
  • Using where:WHERE 条件过滤。

  • Using index:覆盖索引(无需回表)。

  • Using temporary:使用临时表(常见于 GROUP BYORDER BY)。

  • Using filesort:文件排序(需优化索引或查询)。

  • Using join buffer:使用连接缓存(联表查询较大时)。

 4. 常见性能问题

 

  • 全表扫描(type=ALL:未命中索引,需检查 WHERE 条件或添加索引。

  • 未使用索引(key=NULL:可能索引不匹配或统计信息过时。

  • Using filesort/Using temporary:排序或分组未利用索引,需优化 SQL 或索引。

  • rows 值过大:预估扫描行数多,可能导致慢查询。

 5. 优化建议

索引优化 

 

  • 为 WHERE、JOIN、ORDER BY、GROUP BY 涉及的列添加索引。

  • 使用覆盖索引(查询列均在索引中)。

  • 避免冗余索引,定期分析索引使用情况。

 查询优化

  • 避免 SELECT *,仅选择需要的列。

  • 减少子查询,改用 JOIN。

  • 优化复杂查询,拆分为多个简单步骤。

 其他优化

  • 调整 JOIN 顺序,让小表驱动大表。

  • 更新表的统计信息:ANALYZE TABLE table_name;

  • 调整数据库配置(如 join_buffer_sizesort_buffer_size)。

 6. 示例分析

 where  条件未加索引  b 表全表扫描

MySQL执行计划_第3张图片

 添加索引

create index  idx_age on employees(age) ;

 MySQL执行计划_第4张图片

 7. 高级工具

  • EXPLAIN ANALYZE(MySQL 8.0.18+):实际执行查询并输出详细耗时(需谨慎使用,会真实执行查询)。

  • 优化器跟踪(Optimizer Trace):查看优化器的详细决策过程:

SET optimizer_trace = 'enabled=on';
SELECT * FROM ...;  -- 执行查询
SELECT * FROM information_schema.optimizer_trace; 

 

你可能感兴趣的:(mysql,数据库)