Mysql Explain工具介绍

Mysql Explain工具介绍

1.Explain的使用

Explain select * from tb_test; 

查询结果如下图:
在这里插入图片描述

2.Explain分析

select_type:

这个字段意思是查询类型,它有很多个值,这里就只介绍几种常见的值:
(1)simple: 简单查询不包含子查询或union;
(2)primary: 复杂查询最层的select;
(3)subquery: 在from之前的子查询;
(4)derived: 在from之后的子查询(相当于是创建了一个临时表);
例子:

EXPLAIN select (select 1 from tb_test where id = 1) from (select id from tb_user where id = 1) der;

在这里插入图片描述
如上图可见select_type里每一个字段后面table里面就是对应的他查询的表,而且上面的sql语句查询的顺序会根据查询的出来的结果id最大的优先查询,这里查出来的id有可能还是一样的,如果是一样的,就从上往下依次查询。

type:

这个字段个人觉得在这explain分析里面是比较重要的,可根据他的值进行sql优化,他的几个常见的值是 system<const<eq_ref<ref<range<index<all
一般来说得保证sql查询达到range级别,最好能优化到red。

(1)system、const:这两种级别查询效率是非常高了,const就是通过主键索引精准查询,而system可以说是const的一种特殊情况其实是const一种特殊情况,表里只有一条元组匹配时为system ,
EXPLAIN select * from (select * from tb_test WHERE id = 1) sub

在这里插入图片描述

(2)eq_ref:primary key 或 unique key 索引关联查询时,如:
EXPLAIN select ur.* from user_role ur 
left join role r on r.id = ur.role_id

在这里插入图片描述

(3)ref:它与eq_ref的主要区别就是,ref是用的不是唯一索引,例如:
EXPLAIN select * from user where name = 'zyl'

在这里插入图片描述

(4)range:这主要是利用索引范围查询,比如利用in()、between、>、<、= 等操作。
EXPLAIN SELECT * FROM `test` where name > 'qwe'

在这里插入图片描述

(5)index:这种查询一般是走二级索引,是不会从树的根节点快速查询的,而是根据叶子节点遍历和扫描,这种查询多是覆盖查询,效率不是很高,但还是比不走索引的效率要高些。
EXPLAIN SELECT name FROM test;

在这里插入图片描述

(6)all:全表扫描,通常这种情况需要加索引优化
EXPLAIN SELECT * FROM test;

在这里插入图片描述

possible_keys:

这个字段意思是查询可能会用到的索引,因为查询中mysq底层的优化器会优化我们的查询语句,例如我们范围查询时,范围过大,在这种条件下全表扫描是会比索引查询更快的,所以这里可能就不会用到索引查询。

EXPLAIN SELECT * FROM test where name > '1';

在这里插入图片描述
如上图所示,可能会用到索引index_name,但是我们会发现key这个字段下是没有值得,这就是因为mysql底层优化器的原因。

key:

查询会用到的索引,会展示在这里。

EXPLAIN SELECT * FROM test where name = '1';

在这里插入图片描述

key_len:

这个字段意思就是索引字段的字节数,比如设置主键为int类型,字节数大小应该是4,通过主键索引查出来的数据如下图:

EXPLAIN SELECT * FROM test where id = 1;

在这里插入图片描述

以下列举mysql常见类型的字节大小:

类型 字节大小
char(n) n
vachar(n) 如果是utf-8,长度为3n+2,加的2字节是用来存储字符串长度
tinyint 1
smallint 2
bigint 8
date 3
timestamp 4
datetime 8

如果允许字段为空,还会需要1字节来记录是否为空。
索引最大长度是768字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索 引。

EXPLAIN SELECT name FROM test where name = '1';

name类型为vachar(10),按照上面的算法3n+2,字节大小为32,
在这里插入图片描述
查出来会发现大小为33,这里就是加1个字段来存储是否为空

ref:

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

rows:

这一列mysql估计要查询的行数,不是从结果集里面取出来的,只是个估计值。

Extra:

这一列展示的信息也是比较重要的,常见的重要值如下:

(1)Using index:使用覆盖索引

覆盖索引概念:select后面的查询字段能直接从这课b+树上获取,不需要再经过回表查询获取结果。这一般针对的就是辅助索引或者说二级索引。

EXPLAIN SELECT name FROM test where name = '1';

在这里插入图片描述

(2)Using where:使用where条件来查询,未经过索引查询。
EXPLAIN SELECT * FROM test where name > '2';

在这里插入图片描述
一般这种情况都要处理我using index。

(3)Using index condition:查询列不完全被索引覆盖,where条件中有一个前导列的范围。
EXPLAIN  select * from user where name > '1'

在这里插入图片描述

(4)Using temporary:mysql需要创建临时表来处理查询,出现这种情况一般都是要用索引进行处理优化的。
EXPLAIN  select DISTINCT name  from test;

没加索引时:
在这里插入图片描述
加了索引:
在这里插入图片描述

(5)Using filesort:文件排序,这种将用的是外部排序,而不是索引排序。数据较小时在内存中排序,否则将在磁盘中排序,这种一般都要优化为索引排序。
EXPLAIN  select * from test ORDER BY name ;

在这里插入图片描述
优化为索引排序,其实也是用到了覆盖索引的概念。

EXPLAIN  select name  from test ORDER BY name 

在这里插入图片描述

(6)Select tables optimized away:是用某些聚合函数来访问索引字段。
EXPLAIN  select max(name)  from test ;

在这里插入图片描述

3.索引优化实例

(1)全值匹配
EXPLAIN  select  name  from test where name = 'zyl'

在这里插入图片描述

(2)最左前缀法则

使用联合索引时要从索引的最左列开始查而且不可跳过中间的某一个。因为按B+树的原理来说,如果不使用最左前缀法则,底层数据是不能排序的,是走不了索引的。虽然在mysql里面不按照最左前缀法则写sql有可能会走索引,那是因为mysql底层的优化器将sql优化了一遍的,这也是需要耗费资源时间的。

EXPLAIN  select * from user where  name = 'zyl' and age = 18 and birth_date > '2020-01-1';

在这里插入图片描述

EXPLAIN  select * from user where  birth_date > '2020-01-1' ;

在这里插入图片描述

(3)不在索引列上做任何操作(计算、函数、类型转换),会导致索引失效
EXPLAIN  select  *  from test where left(name,3) = 'zyl';

在这里插入图片描述

(4)存储引擎不能使用索引中范围查询右边的索引
EXPLAIN  select * from user where  name = 'zyl' and age = 18 and birth_date > '2020-01-1';
EXPLAIN  select * from user where  name = 'zyl' and age > 18 and birth_date = '2020-01-1';

在这里插入图片描述
在这里插入图片描述

(5)尽量使用覆盖索引减少select *查询方式
EXPLAIN  select  name  from test where name = 'zyl'

在这里插入图片描述

(6)mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描
EXPLAIN  select  *  from test where name != 'zyl';

在这里插入图片描述

(7)is null、is not null 一般情况下也是不能使用索引的
EXPLAIN  select  *  from test where name is not null

在这里插入图片描述

(8)like通配符在左边时,索引会失效
EXPLAIN  select  *  from test where name like '%zyl';

在这里插入图片描述

(9)字符串不加单引号,索引会失效
EXPLAIN  select  *  from test where name = 1;

在这里插入图片描述

(10)少用in或者or,mysql底层的优化器可能会使他们不走索引
EXPLAIN  select  *  from test where name in ('zyl','zl');

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ZYLSKY111/article/details/107478304