MySql EXPLAIN type (mysql 访问类型)是指优化器(mysql 中的一个组件)决定的,用来查找记录的方式,在优化器决定了访问类型之后,具体的查询由执行器和存储引擎执行。

下面的访问类型按照从优到劣出现:

null

mysql 不用访问表就可以得出结果(最简单的情况是 limit = 0,虽然没什么用就是了,或者写了一个奇怪的恒不满足式,或者虚拟表(存疑))。即你的查询在交给存储引擎之前就被拒绝了,完全不查,所以性能最优的(❁´◡`❁)。

const/system

表中最多有一条记录符合查询条件(比如指定主键的值,或者 unique的值)。记录中的其他的值可以被优化器当作常量处理。

eq_ref

查询在一个 unique 索引上进行,即每个索引项对应唯一一条记录。

ref

查询在索引上进行,但一个索引项不唯一,即一个非 unique 的索引,或者是每个联合索引的前缀。

range

查询在索引上进行,不过选取的是索引的范围(查询对存在索引的列使用了 '<','<=','>','>=','between' 等关键词)。索引使用 B+ 树主要的受益查询类型。

index

需要遍历整个索引才能得到结果(查询的字段都包含在索引中,不需要查询记录上非索引的字段,这些字段可以在不同的字段上),例如查询的字段本身是一个索引,或者索引的列作为查询条件的一部分但是需要通过一个计算判断。

为了区别 index 和 all,需要做一点额外的说明。Mysql(Innodb 引擎)的索引使用的数据结构是 B+ 树,在 key/value 对中 key 是索引的值,但是在 value 上主键索引和辅助索引有所不同,主键索引中的 value 的值指向完整的一条记录,而辅助索引的值是主键索引。那么就会存在一个问题,在使用辅助索引获取到主键值之后,需要再一次利用主键索引查询记录的具体地址。这个过程叫做 “回表”。还有一种查询是查询的目标字段就是索引的组成部分,不需要回表,这种情况就叫做“覆盖索引”。

那么区分 index 和 all 的关键就在于有没有回表这一过程。

all

全表扫面,需要读取所有的记录,并且查询的字段没法完全从索引中获取。