explain 所有人都应该很相熟,通过它咱们能够晓得 SQL 是如何执行的,尽管不是 100% 管用,然而至多大多数场景通过 explain 的输入后果咱们能直观的看到执行打算的相干信息。
早一些的版本 explain 还只能查看 select
语句,当初曾经能反对 delete
,update
,insert
,replace
了。
刚开始我想写这个的时候只是因为这个货色经常性不必就遗记,写了发现其实这个货色真的挺麻烦的,要把每个场景都整进去麻烦的很。
id
查问编号,如果没有子查问或者联结查问的话,就只有一条,如果是联结查问的话,那么会呈现一条 id 为 null 的记录,并且标记查问后果,因为 union
后果会放到长期表中,所以咱们看到这里的表名是 <union1,2> 这种格局。
select_type
关联类型,决定拜访表的形式。
SIMPLE
简略查问,代表没有子查问或者union
。
PRIMARY
如果不是简略查问,那么最外层查问就会被标记成 PRIMARY。
UNION&UNION RESULT
从上图能够看进去了,蕴含联结查问,第一个被标记成了PRIMARY
,union 之后的查问被标记成UNION
,以及最初产生的UNION RESULT
DERIVED
用来标记呈现在 from 里的子查问,这个后果会放入长期表中,也叫做派生表。
这个对于低版本的 Mysql 可能显示是这样的,高一点可能你看到的还是 PRIMARY,因为被 Mysql 优化了。我换一个版本的 Mysql 和 SQL 执行能够验证到这个后果。
SUBQUERY
不在 from 里的子查问。
DEPENDENT
代表关联子查问(子查问应用了内部查问蕴含的列),和 UNION
,SUBQUERY
组合产生不同的后果。
UNCACHEABLE
代表不能缓存的子查问,也能够和 UNION
,SUBQUERY
组合产生不同的后果。
MATERIALIZED
物化子查问是 Mysql 对子查问的优化,第一次执行子查问时会将后果保留到长期表,物化子查问只须要执行一次。
比方上述 DERIVED 就是物化的一种体现,与之对应的就是 DEPENDENT,每次子查问都须要从新调用。
这个后果无奈直观的看进去,能够用 FORMAT=JSON
命令查看 materialized_from_subquery
字段。
table
显示表名,从上述的一些图中能够察看到 UNION_RESULT 和 DERIVED 显示的表名都有一些本人的命名规定。
比方 UNION_RESULT 产生的是 <unionM,N>,DERIVED 产生的是 <derivedN>。
partitions
数据的分区信息,没有分区疏忽就好了。
type
关联类型,决定通过什么形式找到每一行数据。以下依照速度由快到慢。
system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL。
system&const
这通常是最快的查找形式,代表 Mysql 通过优化最终转换成常量查问,最惯例的做法就是间接通过主键或者惟一索引查问。
而 system 是 const 的一个特例(只有一行数据的零碎表),轻易找一张零碎表,就插入一条数据就能够看到 system 了。
eq_ref
通常通过主键索引或者惟一索引查问时会看到 eq_ref,它最多只返回一条数据。user_id
是惟一索引,为了测试就关联以下主键索引。
ref
也是通过索引查找,然而和 eq_ref 不同,ref 可能匹配到多条符合条件的数据,比方最左前缀匹配或者不是主键和惟一索引。
最简略的方法,轻易查一个一般索引就能够看到。
fulltext
应用 FULLTEXT 索引
ref_or_null
和 ref 相似,然而还要进行一次查问找到 NULL 的数据。
这相当于是对于 IS NULL 查问的优化,如果表数据量太少的话,你或者能看到这里类型是全表扫描。
index_merge
索引合并是在 Mysql5.1 之后引入的,就像上面的一个 OR 查问,依照原来的想法要么用 name 的索引,要么就是用 age 的索引,有了索引合并就不一样了。
对于这种单表查问(无奈跨表合并)用到了多个索引的状况,每个索引都可能返回一个后果,Mysql 会对后果进行取并集、交加,这就是索引合并了。
unique_subquery
依照官网文档所说,unique_subquery 只是 eq_ref 的一个特例,对于下图中这种 in
的语句查问会呈现以进步查问效率。
因为 Mysql 会对 select 进行优化,根本无奈呈现这个场景,只能用 update 这种语句了。
index_subquery
和 unique_subquery 相似,只是针对的是非惟一索引。
range
看名字就晓得,范畴查问,其实就是带有限度条件的索引扫描。
常见的范畴查问比方between and
,>,<,like,in 都有可能呈现 range。
index
跟全表扫描相似,只是扫表是依照索引程序进行。
ALL
全表扫描,没啥好说的。
possible_keys
能够应用哪些索引。
key
理论决定应用哪个索引。
key_len
索引字段的可能最大长度,不是表中理论数据应用的长度。
ref
示意 key 展现的索引理论应用的列或者常量。
rows
查问数据须要读取的行数,只是一个预估的数值,然而能很直观的看出 SQL 的优劣了。
filtered
5.1 版本之后新增字段,示意针对合乎查问条件的记录数的百分比估算,用 rows 和 filtered 相乘能够计算出关联表的行数。
Extra
解析查问的附加额定信息,这个太多了,有趣味能够本人看官网文档,只列举一些常见的。
Using index
应用笼罩索引。
Using index condition
应用索引下推,索引下推简略来说就是加上了条件筛选,缩小了回表的操作。
Using temporary
排序应用了长期表。
Using filesort
应用内部索引文件排序,然而不能从这里看出是内存还是磁盘排序,咱们只能晓得更耗费性能。
Using where
where 过滤,没啥好说的。
Zero limit
除非你写个 LIMIT 0。
Using sort_union(), Using union(), sing intersect()
应用了索引合并,参看上文。
总结