这是一个 explain 学习笔记系列,目的时帮助大家看懂 explain 各个输出项的作用和意义,从而可以针对性地提升查询语句的性能。
承接第一篇,上篇介绍到 select_type,本篇继续介绍后续各列的内容。
列详解
type
前面说过,执行计划的一条记录代表 Mysql 对某个表执行查询时的访问方法,而 type 就是表明这个访问方法是什么:
| name | desc |
|---|---|
| system | 表只有一条数据且表使用的存储引擎 MyISAM,Memory 的统计数据是精确的,则为 system |
| const | 根据主键或者唯一二级索引与常数进行等值匹配,对单表访问就是 const |
| eq_ref | 连接查询中,被驱动表通过主键或是不允许存储 Null 的唯一二级索引进行等值匹配 |
| ref | 普通二级索引和常量进行等值匹配,对该表的访问方式可能是 ref |
| fulltext | 全文索引 |
| ref_or_null | 对普通二级索引进行等值匹配,且索引值可以为 NULL,此时的访问方法可能为 ref_or_null |
| index_range | 索引合并 |
| unique_subquery | 包含 in 的查询中,查询优化器将子查询优化成 Exist 查询,且子查询转换之后类似 eq_ref 的查询 |
| index_subquery | 与 unique_subquery 类似,不过在访问子查询时用的普通索引 |
| range | 使用所以获取某些单点扫描区间记录,可能会使用到 range 的访问方法 |
| index | 索引覆盖时,但需要访问全部的索引记录时,访问单表的方式就是 index;在 innodb 中,需要执行全表扫描,同时需要对主键进行排序时,访问方式也为 index |
| all | 全表扫描。也是最慢的访问方式 |
key_len
当我们希望从执行中直接看出形成扫描区间的边界条件时什么,这个时候 key_len 就有用了。
而 key_len 由以下几部分组成:
- 该列实际数据最多占用的存储空间长度:
- 如
int最多占用空间长度为 4 字节(不论存什么都是 4 字节) - 变长字段。如
utf8字符集,类型varchar(100)列来说,实际数据最多占用存储空间为字符集表示 一个字符最多占用字节数 ✖️该类型最多存储字符数的积,也就是3✖️100=300字节
- 如
- 该列可以存储
NULL,则key_len会在前面的基础上 + 1 字节 - 对于变长列,会有 2 字节来存储变列的实际数据占有空间,则
key_len会在前基础上 + 2 字节
ref
当访问方式为:const, eq_ref, ref, ref_or_null, unique_subquery, index_subquery 其中一个时,ref 列展示的就是与索引列进行等值匹配的值,比如只是一个常数或者是某个列。