1 EXPLAIN执行结果下各字段含义
(1) id
- 含义:标识查询中每个 SELECT 子句的唯一编号。
- 规则:
- 相同 id:按从上到下的顺序执行。
- 不同 id:值越大,优先级越高(先执行)。
- NULL:表示该行是 UNION 或 DERIVED 的结果。
(2) select_type
- 含义:查询的类型,描述查询的复杂性。
- 常见类型:
- SIMPLE:简单查询(无子查询或 UNION)。
- PRIMARY:最外层的 SELECT。
- UNION:UNION 中的第二个或后续 SELECT。
- DERIVED:派生表(FROM 子句中的子查询)。
- SUBQUERY:子查询中的第一个 SELECT。
(3) table
- 含义:当前行数据对应的表名。
- 示例:如果是派生表(子查询),会显示 。
(4) partitions
- 含义:涉及的分区信息(如果表是分区表)。
- 值为 NULL:未使用分区。
(5) type
- 含义:连接类型(访问方法),反映查询性能。
- 性能排序(从优到劣):
- system > const > eq_ref > ref > range > index > ALL。
- 关键类型说明:
- const:通过主键或唯一索引查询单条记录(如 WHERE id=1)。
- ref:非唯一索引的等值匹配(可能返回多行)。
- range:索引范围扫描(如 BETWEEN、IN)。
- ALL:全表扫描(需优化索引或查询条件)。
(6) possible_keys
- 含义:查询可能使用的索引列表。
- 值为 NULL:没有可用索引。
- 优化建议:检查是否遗漏了合适的索引。
(7) key
- 含义:实际使用的索引名称。
- 值为 NULL:未使用索引。
- 优化建议:确保 key 与 possible_keys 一致,避免 MySQL 选择低效索引。
(8) key_len
- 含义:使用的索引长度(字节数)。
- 用途:越短越好(减少 I/O 开销)。
- 示例:key_len=767 表示使用了 VARCHAR(255) 类型的索引。
(9) ref
- 含义:显示索引的哪一列被使用,以及与之比较的值(如常量、列名)。
- 示例:const 表示使用了常量值(如 WHERE name=‘John’)。
(10) rows
- 含义:MySQL 估计需要扫描的行数。
- 优化建议:值越大,性能越差(需优化索引或查询条件)。
(11) filtered
- 含义:表示通过 WHERE 条件过滤后的行百分比(范围 0-100%)。
- 示例:filtered=100 表示所有行都符合条件(无需过滤)。
(12) Extra
- 含义:额外信息,提供查询执行的详细说明。
- 关键值:
- Using where:使用了 WHERE 条件过滤。
- Using index:使用了覆盖索引(仅扫描索引,无需回表)。
- Using filesort:需要额外排序操作(需优化索引或查询)。
- Using temporary:创建了临时表(需优化查询或索引)。
2 如何从MySQL官网搜索EXPLAIN文档
步骤 1:访问 MySQL 官网
- 官网地址:https://dev.mysql.com/
- 文档页面:点击顶部菜单栏的 “Documentation”,进入官方文档中心。
步骤 2:搜索关键词 - 搜索栏:在文档页面右上角的搜索栏中输入 EXPLAIN。
- 筛选版本:选择你需要的 MySQL 版本(如 MySQL 8.0 Reference Manual)。
步骤 3:定位相关章节 - 推荐路径:
a.进入 “Optimization” 章节。
b.查找 “Optimizing Queries with EXPLAIN” 或 “EXPLAIN Output Format”。
c.阅读官方对 EXPLAIN 的详细说明,包括字段解释和示例。
步骤 4:查看官方示例 - 示例:官方文档中通常会提供 EXPLAIN 的完整示例,帮助你理解如何分析执行计划。
- 重点内容:
- EXPLAIN 的语法(如 EXPLAIN SELECT …)。
- 各字段的含义(如 type、key、Extra)。
- 如何通过 EXPLAIN 优化查询性能。
最新版本的EXPLAIN输出结果链接:https://dev.mysql.com/doc/refman/8.4/en/explain-output.html
3 常见问题与优化建议
(1) 如何判断查询是否使用了索引?
- 检查 key 字段是否为 NULL。
- 如果 key 为 NULL,但 possible_keys 有值,说明 MySQL 未选择合适的索引(可手动指定索引:FORCE INDEX(index_name))。
(2) 如何减少 rows 扫描行数? - 为 WHERE 条件中的列添加索引。
- 避免使用 SELECT *,仅查询必要列(减少回表操作)。
(3) 如何避免 Using filesort? - 为排序字段(ORDER BY)添加索引。
- 如果排序字段与查询条件无关,可能需要调整查询逻辑。
(4) 如何避免 Using temporary? - 优化 GROUP BY 或 DISTINCT 操作,确保相关列有索引。
- 避免在 SELECT 中使用复杂的聚合函数。