一条查询语句执行过程
EXPLAIN 基本语法
explain [extended|partition]select
字段说明
字段 | 说明 |
---|---|
id | 执行编号,标识 select 所属的行。如果在语句中没子查询或关联查询,只有唯一的 select ,每行都将显示 1。否则,内层的 select 语句一般会顺序编号,对应于其在原始语句中的位置 |
select_type | 显示本行是简单或复杂select。如果查询有任何复杂的子查询,则最外层标记为PRIMARY(DERIVED、UNION、UNION RESUlT) |
table | 访问查询的表名或表别名 |
partitions | 查询访问的分区 |
type | 表的访问类型( MySQL 如何查询表中的行记录)效率高低:const / eq_ref / ref / range / index / all
|
possible_keys | 可能使用的索引 |
key | 实际使用的索引 |
key_len | 实际使用的索引长度(单位:字节) |
ref | 用于索引查找的值的来源,如果值未常量,则 ref 为 const
|
rows | 预计查询需要扫描的行数(在表或索引树中) |
filtered | 查询条件所过滤的行记录数占比 |
Extra | 额外的信息 |
id
id
为数值,表示在查询过程中,SELECT
语句的执行顺序
- 如果
id
值相同,则执行顺序为:从上到下 - 如果
id
值不同,则执行顺序为:id
值越大的越先执行 - 如果
id
值相同,则可以认为他们是同一分组,同一分组中执行顺序为:从上到下,在所有组中,id
值越大的越先执行 - 如果
id
值为null
,则表示这是一个结果集
select_type
表示查询的类型
类型 | 说明 |
---|---|
SIMPLE | 简单查询(无 NUION、SUBQUERY 的 SELECT 语句) |
PRIMARY | 在复杂查询中,最外层的 SELECT 语句 |
UNION | 在联合查询中,第二个和随后的 SELECT 语句 |
DEPENDENT UNION | 在联合查询中,第二个和随后的 SELECT 语句,并且该 SELECT 语句依赖外层 SELECT 语句 |
UNION RESULT | 联合查询的结果表 |
SUBQUERY | 不在 FROM 子句中的子查询 |
DEPENDENT SUBQUERY | 相关子查询 |
DERIVED | 派生表(在FROM从句中的子查询) |
MATERIALIZED | 物化表(非关联子查询的一种优化类型) |
UNCACHEABLE SUBQUERY | 无法缓存的子查询 |
UNCACHEABLE NUION | 无法缓存的联合查询 |
table
查询访问的表名或别名
关联优化器会为查询选择关联顺序,左侧深度优先
当 from
中有子查询的时候,表名是 derivedN
的形式,N
指向子查询,也就是 explain
结果中的下一列
当有 union result
的时候,表名是 union 1,2
等的形式,1,2
表示参与 union
的 query id
注意:MySQL
对待这些表和普通表一样,但是这些“临时表”是没有任何索引的
partitions
type
类型 | 说明 |
---|---|
NULL | 不需要访问表 |
system | 表中只有一行记录或空表,只能用 myisam 和 memory 表 |
const | 当 MySQL 对查询进行优化将其转换成常量时,就会使用这个值 |
eq_ref | 出现在多表连接查询中,驱动表只有一行记录,同时连接字段都是非空唯一索引 |
ref | 非唯一索引查找(或唯一索引的前缀查找) |
fulltext | 全文索引查找 |
ref_or_null | 与 ref 类型一致,只是增加了 NULL 的对比, |
unique_subquery | 代替 eq_ref 针对 IN 子查询的优化, IN 子句返回唯一索引 |
index_subquery | 与 unique_subquery 相似,但 IN 子句返回非唯一索引 |
range | 索引范围扫描,使用 BETWEEN、IN、>、>=等运算符对索引字段值进行比较 |
index_merge | 使用多个索引匹配查找,最终获取合并结果(交集 AND 、并集 OR ) |
index | 全索引扫描 |
ALL | 全表扫描 |
possible_keys
显示查询使用了哪些索引,表示该索引可以进行高效地查找,但是列出来的索引对于后续优化过程可能是没有用的
key
key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
key_len
key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好 。
ref
ref列显示使用哪个列或常数与key一起从表中选择行。
rows
rows列显示MySQL认为它执行查询时必须检查的行数。注意这是一个预估值。
filtered
存储引擎层返回给 MySQL 后,MySQL server 层过滤后,剩下满足条件的行数比例
Extra
Extra是EXPLAIN输出中另外一个很重要的列,该列显示MySQL在查询过程中的一些详细信息,MySQL查询优化器执行查询的过程中对查询计划的重要补充信息。
类型 | 说明 |
---|---|
Using filesort | 说明 MySQL 无法利用索引排序,进行了额外的排序 |
Using temporary | 使用的临时表 |
Using index | 使用索引覆盖,不需要扫描原表,直接通过索引扫描就能得到想要的数据 |
Using index condition | 使用索引条件过滤 |
Using where | 通过 WHERE 从句的条件来筛选存储引擎返回的行记录 |
Using join buffer | 使用了连接缓存:Block Nested Loop,连接算法是块嵌套循环连接;Batched Key Access,连接算法是批量索引连接 |
impossible where | where子句的值总是false,不能用来获取任何元组 |
select tables optimized away | 在没有GROUP BY子句的情况下,基于索引优化MIN/MAX操作,或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。 |
distinct | 优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作 |