EXPLAIN 是 MySQL 中分析 SQL 查询执行计划的强大工具,用来帮助开发者理解 SQL 是如何被 MySQL 执行的,并据此进行性能优化。
- SQL 是 按什么顺序 访问表的?
- 使用了 什么索引?
- 每个步骤大概 访问了多少行?
- 是否使用了 临时表 或 排序?
- 是否存在 全表扫描、回表查询、冗余操作?
- 索引未命中
- 查询效率低
- 连接方式不合理
- 存在优化空间
EXPLAIN SELECT * FROM your_table WHERE id = 10;
字段名 | 作用 | 示例 | 说明与优化建议 |
---|---|---|---|
id | 查询中执行的阶段序号 | 1,2 | 多表连接时,id 值越大越晚执行。 |
select_type | 查询类型 | SIMPLE、PRIMARY、SUBQUERY、DERIVED | 识别是否为子查询、派生表,便于判断优化方向。 |
table | 当前访问的表名或临时表名 | user |
显示当前行操作的表名。 |
type | 连接类型,重要指标 | ALL、index、range、ref、eq_ref、const、system | 越靠后效率越高。ALL(全表扫描)最差,const/system 最好。 |
possible_keys | 可能用到的索引 | idx_user_id | 是建议,说明哪些索引可以用。 |
key | 实际使用的索引 | idx_user_id | 如果为 NULL ,说明索引未使用。 |
key_len | 使用索引的长度(字节) | 4,8 | 越接近定义索引字段的长度越好。可判断是否用到联合索引的所有字段。 |
ref | 哪个字段与索引匹配 | const,table.column | 显示使用了哪个字段进行条件匹配。 |
rows | MySQL 预估要扫描的行数 | 10,000 | 行数越多,SQL 负担越重,需优化。 |
filtered | 返回的行数占比估算(百分比) | 10.0 | 表示 WHERE 条件过滤后的行数比例。 |
Extra | 额外信息 | Using filesort、Using temporary | 显示额外操作,重点关注是否出现 filesort、temporary 等性能隐患 |
重点字段 | 关注理由 | 优化方向 |
---|---|---|
type |
反映了 MySQL 访问数据的方式 | 尽量避免 ALL (全表扫描),建议为 ref 、range 、const 等类型 |
key |
是否使用了索引 | 若为 NULL 表示未用索引,检查字段是否建了合适索引 |
rows |
扫描的行数 | 行数越多性能越差,优化 WHERE 条件和索引 |
Extra |
是否用到了临时表或排序 | 出现 Using filesort 或 Using temporary 时,建议优化 ORDER BY 、GROUP BY |
key_len |
索引利用情况 | 与 key 结合判断是否完全利用联合索引的多个字段 |
EXPLAIN SELECT * FROM users WHERE email LIKE '%@gmail.com';
type | key | rows | Extra |
---|---|---|---|
ALL | NULL | 100000 | Using where |
type = ALL:全表扫描
key = NULL:没有用索引
LIKE ‘%xxx’ 开头模糊查询无法用索引
✅ 优化建议: 改为前缀匹配、引入全文索引
工具 | 用途 |
---|---|
EXPLAIN |
快速分析执行计划 |
EXPLAIN FORMAT=JSON |
提供更详细的执行信息 |
SHOW INDEX FROM tablename |
查看表中索引 |
ANALYZE TABLE tablename |
更新统计信息,优化执行计划 |
EXPLAIN ANALYZE (MySQL 8.0+) |
显示实际执行耗时与行数,更接近真实情况 |