EXPLAIN调优

73 阅读4分钟

explain

参考: www.cnitblog.com/aliyiyi08/a…

select_type

  1. SIMPLE : 简单SELECT(不使用UNION或子查询等)
  2. PRIMARY : 我的理解是最外层的select

  1. 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) ;

  1. UNION RESULT : union 的结果

  1. SUBQUERY : 子查询的第一个SELECT

explain select * from t3 where id = (select id from t3 where id=3952602 ) ;

  1. 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 逐渐降低

  1. all: 全表扫描
  2. index: 全索引扫描
  3. range:使用索引范围查询
  4. 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;

  1. ref : 非唯一索引,非主键索引,最左前缀索引查询,可能会找到多个符合条件的行。

explain select * from film where name = "film1"; explain select * from film left join film_actor on film.id = film_actor.film_id;

  1. eq_ref: 唯一索引,主键索引被连接使用,最多只会返回一条符合条件的记录

explain select * from film_actor left join film on film_actor.film_id = film.id; 这可能是在 const 之外最好的联接类型了,简单的 select 查询不会出现这种 type。

  1. 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 会对结果使用一个外部索引排序,而不是按索引次序从表里读取行,索引不满足排序需求