【MySQL】EXPLAIN type字段详解

355 阅读2分钟

type

💡 system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > all

SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,最好是 consts级别。(阿里巴巴 开发手册要求)

system

💡 当表中**`只有一条记录`**并且该表使用的存储引擎的统计数据是精确的,比如MyISAM、Memory,那么对该表的访问方法就是**`system` **。比方说我们新建一个**`MyISAM`**表,并为其插入一条记录:
mysql> CREATE TABLE t(i int) Engine=MyISAM;
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO t VALUES(1);
Query OK, 1 row affected (0.01 sec)

const

当我们根据主键或者唯一二级索引列常数进行等值匹配时,对单表的访问方法就是**const**, 比如:

 mysql> EXPLAIN SELECT * FROM s1 WHERE id = 10005;

eq_ref

💡 在连接查询时,如果被驱动表是通过主键或者唯一二级索引列等值匹配的方式进行访问的(如果该主键或者唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较)。则对该被驱动表的访问方法就是**`eq_ref`**,比方说:
 mysql> EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.id = s2.id;

Untitled

从执行计划的结果中可以看出,MySQL打算将s2作为驱动表,s1作为被驱动表,重点关注s1的访问 方法是 eq_ref ,表明在访问s1表的时候可以 通过主键的等值匹配 来进行访问。

ref

💡 当通过普通的二级索引列与常量进行等值匹配时来查询某个表,那么对该表的访问方法就可能是**`ref`**,比方说下边这个查询:
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';

fulltext

💡 全文索引

ref_or_null

💡 当对普通二级索引进行等值匹配查询,该索引列的值也可以是**`NULL`**值时,那么对该表的访问方法就可能是**`ref_or_null`**,比如说:
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key1 IS NULL;

index_merge

unique_subquery

index_subquery

range

💡 如果使用索引获取某些单点区间扫描的记录,那么就是`range`访问方法。
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key1 IS NULL;

mysql> EXPLAIN SELECT * FROM s1 WHERE key1 > "a" AND key2 < "b";

index

💡 当我们可以使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是`index`,比如这样:
mysql> EXPLAIN SELECT key_part2 FROM s1 WHERE key_part3 = 'a';

上述查询中的所有列表中只有key_part2 一个列,而且搜索条件中也只有 key_part3 一个列,这两个列又恰好包含在idx_key_part这个索引中,可是搜索条件key_part3不能直接使用该索引进行**refrange方式的访问,只能扫描整个idx_key_part索引的记录,所以查询计划的type列的值就是index**。

all

💡 全表扫描