关于sql:听说你对explain-很懂

6次阅读

共计 2534 个字符,预计需要花费 7 分钟才能阅读完成。

explain 所有人都应该很相熟,通过它咱们能够晓得 SQL 是如何执行的,尽管不是 100% 管用,然而至多大多数场景通过 explain 的输入后果咱们能直观的看到执行打算的相干信息。

早一些的版本 explain 还只能查看 select 语句,当初曾经能反对 deleteupdateinsertreplace 了。

刚开始我想写这个的时候只是因为这个货色经常性不必就遗记,写了发现其实这个货色真的挺麻烦的,要把每个场景都整进去麻烦的很。

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

代表关联子查问(子查问应用了内部查问蕴含的列),和 UNIONSUBQUERY 组合产生不同的后果。

UNCACHEABLE

代表不能缓存的子查问,也能够和 UNIONSUBQUERY 组合产生不同的后果。

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()

应用了索引合并,参看上文。

总结

正文完
 0