Explain详解(mysql 5.7 innodb)
Explain的列
sql语句每一个select对应explain的每一行记录。
- id列
id列是每个select的序列号。id越大执行的优先级超高,id相等时由上而下执行。 - select_type列
select_type表示一条sql语句的类型。- simple:简单查询。sql语句中不包含子查询和union。
- primary:最外层的查询语句。当包含子查询或union时。
- subquery:select语句中的子查询。
- derived:from语句中的子查询。
- union:union后的查询。
- table列
table列表示当前查询的是哪张表。
derivedN表示查询当前explain记录中derived id = N的派生表。 - type列
type表示查询语句的关联类型和访问类型。 即MySQL查找记录的方式和范围。
从优到劣的顺序为:const–>system–>eq_ref–>ref–>range–>index–>ALL
多数情况下我们通过此字段判断sql的一个执行情况,一般sql要优化到range/ref级别- const
表中只有一条数据。 - system
当sql命中primary key 或者 unique key时,并且只检索一次。 - eq_ref
primary key 或者 unique key 做为链接,最多只会返回一条记录。 - ref
命中普通索引或者唯一索引部分前缀,并且只检索一次,可能返回多条记录。 - range
常出现在in,between、<、>、<=、>=等操作中。使用索引检索范围。 - index
扫描全索引(二级索引)。这种检索方式不是从根节点开始检索,而是扫描全部叶子节点。 - ALL
全表扫描。相比index全表扫描扫的是主键索引所有叶子节点。我们知道innodb主键索引包含的数据和索引,相比于扫全部二级索引会更慢。
- const
- possible_keys列
此列会显示mysql分析出的应该要走到的索引。 - key列
此列显示真正执行sql时命中的索引。 - key_len列
此列显示命中索引长度。 - ref列
此显示了在key列记录的索引中用到的列或常量,常见的有:const(常量),字段名(例:film.id)。 - rows列
此列显示了mysql预估的扫描行数。 - extra列
此列显示一些额外信息。如Using where,Using index,Using filesort等
Using filesort : 排序的时候没用到索引而是使用了文件排序。
单路排序:直接查出所有的记录,在sort buffer进行排序。利用trace工具,当sort_mode为<sort_key,additional_fields>或者<sort_key,packed_additional_fields>时,用的是单路排序。
双路排序:查出rowId(行所在的索引)及排序字段,在sort buffer里排序完在回表。当sort_mode为<sort_key,rowid>时,用的是双路排序。
单双路排序的判断依据:通过比较系统变量max_length_for_sort_data(默认1024字节) 的大小和需要查询的字段总大小来判断使用哪种排序模式。- 如果字段的总长度小于max_length_for_sort_data ,使用单路排序。
- 如果字段的总长度大于max_length_for_sort_data ,使用双路排序。