explain
explain以一种可视化的形式, 帮我们近似展示SQL底层执行的状态/执行计划
各个结果字段意义
id
id标识符。这是查询中的SELECT的序列号. 我们一般通过id值的大小研究查询中的逻辑顺序. (但是需要注意的是,它不一定完全代表真实绝对的SQL执行顺序, 是一种逻辑上的相对顺序, 在一些特殊操作中未必按照如下说明).
id不同时:id值越大,优先级越高,越先被执行
id既有相同又有不同时:不同的id值,id值越大,优先级越高,越先被执行; 相同的id值,按照从上到下的顺序执行
select_type
使用的查询类型。如普通查询、联合查询、子查询等
常见类型:
类型 描述 SIMPLE 简单的查询 (查询中不包含子查询或者UNION) PRIMARY 外层查询 (查询中若包含任何复杂的子部分) SUBQUERY 子查询 DERIVED 派生表 UNION 一般属于第二个SELECT, 出现在UNION之后,则被标记为UNION UNION RESULT 从UNION表获取结果的SELECT
table
表名
partitions
分区。只对设置了分区的表有意义,现在是NULL,暂时忽略。
type
显示MySQL访问表的方式(比如访问索引,全表扫描等)
性能从好到坏:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
常见字段 表示含义 system 系统表,或者极少量数据,往往不需要进行磁盘IO const 常量连接(常数级时间复杂度, 基本上是命中主键) eq_ref 多表关联查询时,主键索引或唯一索引作为关联条件进行等值扫描 re f 非主键或者非唯一索引等值扫描 range 范围扫描 index 全索引扫描 (比如修改表中数据, 导致所有索引结构变化) ALL 全表扫描 … …
possible_keys
SQL执行中有可能用到的索引
- 这列数据是在SQL在优化器初步解析时生成,随着进一步优化,该列索引不一定使用
key
SQL执行中实际用到的索引
- 如果为NULL,则没有使用
key_len
↑上面的key占用的字节数
索引类型为int时,占用4字节
long占用8字节
float占用4字节
若key是非主键索引:
比如索引是一个student_name列
- 类型为varchar(20)
- 使用utf8mb4编码(含义是utf8 most bytes 4,所以最多占用4个字节)
- 允许为null
那么key_len = 20 * 4 + 1(NULL)+ 2 (存储实际数据长度)
展开说说NULL与描述长度
- 数据允许为null,则需额外占1个字节,所以索引字段最好不要允许为null
- 在InnoDB存储引擎中,索引中的变长字段通常使用2个字节来存储长度前缀。比如在数据为武松时(在utf8mb4中一个汉字占3字节,所以武松需要占6字节)而那2字节就是用来存储
6
这个数字。2个字节可表示的最大长度为65535(2^16 - 1)
ref
用于查找行的列或常量
表示将哪个字段或常量和key列所使用的字段进行比较。
rows
优化器预计扫描的行数
这个数字是基于表统计信息(如索引统计、行数估计等)估算的,不是确切值
通常情况下,
rows
值越小,意味着查询需要处理的数据量越少,性能越好
filtered
MySQL 预计从该步骤的扫描行中留下的行数,占总扫描行数的比例
单位是百分比,是对rows进一步过滤的比例
- 举例:如果
rows
是 1000,filtered
是10.00
,表示查询计划预计扫描的行数中大约 10% 会通过 WHERE 子句的过滤条件,则查询返回的行数大约是1000 * 10% = 100
作用:它帮助评估过滤条件的效率。如果
filtered
值较高,说明大部分行都满足过滤条件;而较低的值则表明大部分行被过滤掉,可能意味着查询需要扫描大量行却只保留少量数据。
Extra
额外信息
显示了MySQL在查询过程中的一些详细信息。
值 描述 Using filesort 说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取, 也称为文件排序. Using temporary 使了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。 USING index 是否用了覆盖索引 Using where 表明使用了where过滤 Impossible where where子句的值总是false,不能用来获取任何元组 … …