explain
参考: www.cnitblog.com/aliyiyi08/a…
select_type
SIMPLE: 简单SELECT(不使用UNION或子查询等)PRIMARY: 我的理解是最外层的select
UNION: UNION中的第二个或后面的SELECT语句, 前面的是PRIMARY
explain select * from t3 where id=3952602 union all select * from t3 ;
4.
DEPENDENT UNION : UNION中的第二个或后面的SELECT语句,取决于外面的查询
explain select * from t3 where id in (select id from t3 where id=3952602 union all select id from t3) ;
UNION RESULT: union 的结果
SUBQUERY: 子查询的第一个SELECT
explain select * from t3 where id = (select id from t3 where id=3952602 ) ;
DEPENDENT SUBQUERY: 子查询中的第一个SELECT,取决于外面的查询
explain select id from t3 where id in (select id from t3 where id=3952602 ) ;
8.DERIVED : 派生表的SELECT(FROM子句的子查询)
explain select * from (select * from t3 where id=3952602) a ;
table
显示这一行的数据是关于哪张表的,有时不是真实的表名字
explain select * from (select * from ( select * from t3 where id=3952602) a) b;
## type 连接使用了哪种类别,有无使用索引 null , system , const , eq_ref , ref , range , index , all 逐渐降低
all: 全表扫描index: 全索引扫描range:使用索引范围查询index_merge:索引合并 , 2个索引or查询
explain select * from role where id = 11011 or tenant_id = 8888; 5.
ref_or_null:类似ref,但是可以搜索值为NULL的行 explain select * from film where name = "film1" or name is null;
ref: 非唯一索引,非主键索引,最左前缀索引查询,可能会找到多个符合条件的行。
explain select * from film where name = "film1"; explain select * from film left join film_actor on film.id = film_actor.film_id;
eq_ref: 唯一索引,主键索引被连接使用,最多只会返回一条符合条件的记录
explain select * from film_actor left join film on film_actor.film_id = film.id;
这可能是在 const 之外最好的联接类型了,简单的 select 查询不会出现这种 type。
const, system:mysql能对查询的某部分进行优化并将其转化成一个常量,用于 primary key 或 unique key 的所有列与常数比较时,所以表最多有一个匹配行,读取1次,速度比较快。
explain extended select * from (select * from film where id = 1) tmp;
使用:
show warnings;system是const的特例,system表里只有1行数据
9.null:优化过程中分解语句,至不用访问表或索引
例如从一个索引列里选取最小值可以通过单独索引查找完成 explain select min(id) from film;
possible_keys
可能使用哪些索引来查找,有时 key 显示 NULL 的情况,种情况是因为表中数据不多,mysql认为索引对此查询帮助不大,选择了全表查询。
key
mysql实际采用哪个索引来优化对该表的访问 如果没有使用索引,则该列是 NULL。如果想强制mysql使用或忽视possible_keys列中的索引,在查询中使用 force index、ignore index。
key_len
显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列
-
字符串 char(n):3n(utf-8)字节长度 varchar(n):2字节存储字符串长度,如果是utf-8,则长度 3n + 2
-
数值类型 tinyint:1字节 smallint:2字节 int:4字节 bigint:8字节
-
时间类型 date:3字节 timestamp:4字节 datetime:8字节
-
如果字段允许为 NULL,需要1字节记录是否为 NULL
ref列
这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),func,NULL,字段名(例:film.id)
rows
这一列是mysql估计要读取并检测的行数,注意这个不是结果集里的行数。
Extra
展示的是额外信息
distinct: 一旦mysql找到了与行相联合匹配的行,就不再搜索了
explain select distinct name from film left join film_actor on film.id = film_actor.film_id;
Using index: 这发生在对表的请求列都是同一索引的部分的时候,返回的列数据只使用了索引中的信息,而没有再去访问表中的行记录。是性能高的表现。
explain select id from film order by id;
Using where:mysql服务器将在存储引擎检索行后再进行过滤。就是先读取整行数据,再按 where 条件进行检查,符合就留下,不符合就丢弃。
Using temporary:mysql需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想到用索引来优化。
Using filesort:mysql 会对结果使用一个外部索引排序,而不是按索引次序从表里读取行,索引不满足排序需求