explain的理解

Explain简介

主要用来展示sql的执行过程

explain select * from t1 where k between 3 and 5;

 

 

 

Explain字段意义

1、id

查询执行计划的唯一标识

2、select_type

select_type 表示对应行是是简单还是复杂的查询

1)SIMPLE

简单查询

2)PRIMARY

复杂查询中的最外层select

3)UNION

3、table

这一列表示 explain 的一行正在访问哪个表。

4、partitions

查询将匹配记录的分区。该值适用NULL于未分区的表

5、type

联接类型。

1)system

该表只有一行(=系统表)。这是const联接类型的特例 

2)const

该表最多具有一个匹配行,该行在查询开始时读取。因为只有一行,所以优化器的其余部分可以将这一行中列的值视为常量。 const表非常快,因为它们只能读取一次。

例如:

SELECT * FROM tbl_name WHERE primary_key=1;

SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2;

3)eq_ref

primary key 或 unique key 索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录。这可能是在 const 之外最好的联接类型了,简单的 select 查询不会出现这种 type。

explain select * from film_actor left join film on film_actor.film_id = film.id;

4)ref

相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行

explain select * from film where name = "film1";

explain select * from film left join film_actor on film.id = film_actor.film_id;

 

 

 5)fulltext

使用fulltext索引执行连接

6)ref_or_null

这种连接类型类似于 ref,但是除了MySQL会额外搜索包含NULL值的此联接类型优化最常用于解析子查询。在以下示例中,MySQL可以使用 ref_or_null联接进行处理

explain select * from film where name="mwy" or name is null

 

 

7)index_merge

此联接类型指示使用索引合并优化。在这种情况下,key输出行中的列包含所用索引的列表,并且key_len包含所用索引 的最长键部分的列表

8)range

范围扫描通常出现在 in(), between ,> ,<, >= 等操作中。使用一个索引来检索给定范围的行。

explain select * from film where id >3;

9)index

和ALL一样,不同就是mysql只需扫描索引树,这通常比ALL快一些。

explain select count(*) from film;

10)all

即全表扫描,意味着mysql需要从头到尾去查找所需要的行。通常情况下这需要增加索引来进行优化了

explain select * from actor;

 

 

 

6、possible_keys

这一列显示查询可能使用哪些索引来查找。 

explain 时可能出现 possible_keys 有列,而 key 显示 NULL 的情况,这种情况是因为表中数据不多,mysql认为索引对此查询帮助不大,选择了全表查询。 

如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查 where 子句看是否可以创造一个适当的索引来提高查询性能,然后用 explain 查看效果。

7、key

查询语句实际使用了那些索引,

如果没有使用索引,则该列是 NULL。如果想强制mysql使用或忽视possible_keys列中的索引,在查询中使用 force index、ignore index。

8、key_len

这一列显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。 

举例来说,film_actor的联合索引 idx_film_actor_id 由 film_id 和 actor_id 两个int列组成,并且每个int是4字节。通过结果中的key_len=4可推断出查询使用了第一个列:film_id列来执行索引查找。

explain select * from film_actor where film_id = 2;

 

 

 

key_len计算规则如下:

  • 字符串
    • char(n):n字节长度
    • varchar(n):2字节存储字符串长度,如果是utf-8,则长度 3n + 2
  • 数值类型
    • tinyint:1字节
    • smallint:2字节
    • int:4字节
    • bigint:8字节  
  • 时间类型 
    • date:3字节
    • timestamp:4字节
    • datetime:8字节
  • 如果字段允许为 NULL,需要1字节记录是否为 NULL

索引最大长度是768字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索引。

9、ref

这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),func,NULL,字段名(例:film.id)

10、rows

这一列是mysql估计要读取并检测的行数,注意这个不是结果集里的行数。

11、filtered

12、extra

这一列展示的是额外信息。常见的重要值如下: 

distinct: 一旦mysql找到了与行相联合匹配的行,就不再搜索了

Using index:这发生在对表的请求列都是同一索引的部分的时候,返回的列数据只使用了索引中的信息,而没有再去访问表中的行记录。是性能高的表现。

Using where:mysql服务器将在存储引擎检索行后再进行过滤。就是先读取整行数据,再按 where 条件进行检查,符合就留下,不符合就丢弃。

Using temporary:mysql需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想到用索引来优化。

Using filesort:mysql 会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。此时mysql会根据联接类型浏览所有符合条件的记录,并保存排序关键字和行指针,然后排序关键字并按顺序检索行信息。这种情况下一般也是要考虑使用索引来优化的。

posted on 2019-12-17 15:49  yivy  阅读(375)  评论(0)    收藏  举报

导航