1. Explain 命令
Explain 可用来分析SQL的执行计划。字段含义如下:
列名 | JSON 名称 | 意义 |
---|---|---|
id | select_id | SELECT标识符 |
select_type | SELECT类型 | |
table | table_name | 输出行的表 |
partitions | partitions | 匹配的分区 |
type | access_type | 连接类型 |
possible_keys | possible_keys | 可供选择的指标 |
key | key | 实际选择的指标 |
key_len | key_length | 所选密钥的长度 |
ref | ref | 与索引相比的列 |
rows | rows | 估计要检查的行 |
filtered | filtered | 按表条件过滤的行的百分比 |
Extra | 附加信息 |
1. id
SELECT 的执行编号,标识 sql 语句执行的顺序。
- 数字越大越先执行,数字相同,从上往下依次执行
- 无嵌套时,一般都是1,嵌套查询时会顺序编号,对应于其在原始语句中的位置
- 值可能为 NULL ,如果这一行用来说明的是其他行的联合结果
2. select_type
查询类型,用于区分是普通查询、子查询或联合查询。
类型 | 说明 |
---|---|
SIMPLE |
简单子查询,不包含子查询和联合查询 |
PRIMARY |
包含联合查询或者子查询中,最外层的查询 |
UNION |
位于 union 中第二个及其后的子查询被标记为 UNION ,第一个就被标记为 PRIMARY ,如果是 union 位于 from 中则标记为 DERIVED |
DEPENDENT UNION |
UNION 中依赖了外部查询的 |
UNION RESULT |
从 union 中获取结果的查询 |
SUBQUERY |
在 select 或者 where 列表中包含子查询,并且不在 from 子句中 |
DEPENDENT SUBQUERY |
SUBQUERY 中依赖了外部查询的 |
DERIVED |
在 form 中包含的子查询, MySQL 会递归将其放在临时表中,称为派生表 |
DEPENDENT DERIVED |
DERIVED 中依赖了外部查询的 |
MATERIALIZED |
物化子查询 |
UNCACHEABLE SUBQUERY |
一个子查询的结果不能被缓存 |
UNCACHEABLE UNION |
表示 union 的查询结果不能被缓存 |
3. table
表示当前这一行正在访问的表名或别名,可能是临时表或者 union 合并结果集。
- 关联优化器会为查询选择关联顺序,左侧深度优先
- 当 from 中有子查询时,表名是
<derivedN>
的形式,N 指向子查询,也就是 explain 结果中的下一列 - 当有
UNION RESULT
时,表名是<unionM,N>
等的形式,M,N 表示参与 union 的查询 id - 当引用值为物化子查询时,表名是
<subqueryN>
的形式,N 是子查询 id
4. partitions
当前查询匹配记录的分区,无分区表,返回 NULL 。
5. type(重点)
连接类型,表示以何种方式去访问数据库,性能从好到坏排序如下:
system
:表仅有一行(相当于系统表),是const
类型的特列。const
:表最多有一个匹配行,是针对主键或唯一索引的等值查询扫描。查询速度非常快, 因为它仅仅读取一次即可。eq_ref
:当进行等值联表查询使用主键索引或者唯一非空索引进行数据查询。ref
:当满足索引的最左前缀规则,或索引不是主键也不是唯一索引时用到。fulltext
:全文索引。ref_or_null
:类似于ref
,但会额外搜索哪些行包含了 NULL,常见于解析子查询。index_merge
:表示使用了索引合并优化,表示一个查询里面用到了多个索引。unique_subquery
:类似于eq_ref
,但是使用了 in 查询,且子查询是主键或者唯一索引。index_subquery
:类似于unique_subquery
,只是子查询使用的是非唯一索引。range
:范围扫描,表示检索了指定范围的行,主要用于有限制的索引扫描。如带有 between 子句或 where 子句里有>、>=、<、<=、is null、<=>、between、like、in
等操作符index
:全索引扫描,当查询仅使用索引中的一部分列时,会使用此类型,有两种情况:- 如果索引是查询的覆盖索引,并且索引查询的数据就可以满足查询中所需的所有数据,则只扫描索引树
- 按索引的顺序来查找数据行,执行了全表扫描
ALL
:全表扫描。
6. possible_keys
展示当前查询可以使用哪些索引,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用。
7. key
表示 MySQL 实际选择的索引。NULL 表示没有选择索引。
8. key_len
显示 MySQL 决定使用的键长度。如果键是 NULL,则长度为 NULL。在不损失精确性的情况下,使用的索引长度越短越好。
9. ref
一般是列名或 const
,表示将哪个字段或常量和键列所使用的字段进行比较。如果 ref
是一个函数,则使用的值是函数的结果。
10. rows(重点)
显示 MySQL 估算会扫描的行数,数值越小越好。
11. filtered
表示引擎返回的数据经过滤后满足查询条件记录数量的百分比,最大为 100。用 rows × filtered
可获得和下一张表连接的行数,如 rows = 1000,filtered = 50%,则和下一张表连接的行数是 500。
12. Extra
显示 MySQL 在查询过程中的一些详细信息,常见的有:
using where
:使用 where 进行条件过滤using index
:表示当前的查询是覆盖索引的,直接从索引中读取数据using temporary
:建立临时表来保存中间结果,查询完成之后把临时表删除,常用于 group by 和 order by 操作中using filtersort
:说明 MySQL 无法利用索引进行排序,只能利用排序算法进行排序using join buffer
:使用连接缓存impossible where
:where 语句的结果总是 false,不会命中任何行impossible having
:having 语句的结果总是 false,不会命中任何行