MySQL性能分析工具(二)——explain的介绍

注: 该SQL语句全部是针对于本地MySQL上的mysqlsenior数据库的 s1,s2表

实例所用表的介绍

s1 表:

CREATE TABLE `s1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `key1` varchar(100) DEFAULT NULL,
  `key2` int(11) DEFAULT NULL,
  `key3` varchar(100) DEFAULT NULL,
  `key_part1` varchar(100) DEFAULT NULL,
  `key_part2` varchar(100) DEFAULT NULL,
  `key_part3` varchar(100) DEFAULT NULL,
  `common_field` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),   主键索引
  UNIQUE KEY `idx_key2` (`key2`),        唯一性索引
  KEY `idx_key1` (`key1`),
  KEY `idx_key3` (`key3`),        普通索引
  KEY `idx_key_part` (`key_part1`,`key_part2`,`key_part3`)        联合索引
) ENGINE=InnoDB AUTO_INCREMENT=20002 DEFAULT CHARSET=utf8

s2 表:

CREATE TABLE `s2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `key1` varchar(100) DEFAULT NULL,
  `key2` int(11) DEFAULT NULL,
  `key3` varchar(100) DEFAULT NULL,
  `key_part1` varchar(100) DEFAULT NULL,
  `key_part2` varchar(100) DEFAULT NULL,
  `key_part3` varchar(100) DEFAULT NULL,
  `common_field` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),    主键索引
  UNIQUE KEY `idx_key2` (`key2`),        唯一性索引
  KEY `idx_key1` (`key1`),
  KEY `idx_key3` (`key3`),    普通索引
  KEY `idx_key_part` (`key_part1`,`key_part2`,`key_part3`)        联合索引
) ENGINE=InnoDB AUTO_INCREMENT=20002 DEFAULT CHARSET=utf8

Id:

作用: 

1: 标识 select 关键字,SQL语句中每写一个 select 就会有一个新的  id 
2:表示表加载的顺序
(1):如果id相同,那么加载表的顺序就是从上至下
(2):id值不同。id值越大的表,对应的优先级越高,越先被执行,如子查询    

应用举例:

(1): explain  select  *  from  s1  inner  join  s2  on  s1.key1  =  s2.key1  where   s1.common_field   =  'a' ;
SQL中只有一个 select,所以 id 只有 1。  s1 在上,说明 s1表先加载,s2后加载 因为 s1是主动表,s2是从动表
(2): explain  select  *  from  s1  where  s1.key1  in  ( select  key3  from  s2) ;
子查询,肯定是先查询 s2 表,根据 s2 表的结果查询 s1表

Select_type:

作用:

一个查询SQL中可能包含多个小查询,每一个小查询都有一个 select_type 属性
               表示当前小查询在整个查询SQL中扮演什么角色

应用举例:

(1): explain select * from s1 union select * from s2;
Union关键字会把两个表的结果联合起来,组成一个临时表
外层的查询 select_type = primary   ,内层的查询 select_type = union 
(2): explain  select  *  from  s1  where  s1.key1  in  ( select  key3  from  s2) ;

Type:

情况一:type  = null ; 根本不需要用到表:

explain   select  now();

情况二:

type = const;  用到了主键、唯一性索引 ,且查询的数据只有一条

select  *  from  s1  where  id  =  18645;

explain  select  *  from  s1  where  s1.key2  =  12136 ;

情况三

type = eq_ref; 用到了主键索引,但却是关联查询
explain  select  *  from  s1  inner  join  s2  on  s1.id  =  s2.id ;
注: 因为 s1 表是要全部扫描的,所以走全表查询
       扫完一条 s1 中的数据就根据s1的id 去匹配 s2 中的 id 字段
       相当于  s2 中依旧是走的主键索引,但是整体是一个联表查询,所以 type = eq_ref

情况四:

type = ref   用到了非主键索引,查询数据只有一条
select  *  from  s1  where  s1.key1 = 'bmicNI';

情况五:

type = range;  用到了索引,但是查询的数据是一个范围
explain  select  *  from  s1  where  id  > 15000  and  id  < 15100;

情况六:

type = index; 查询用到了索引,但是查询索引的全部,
explain  select  id  from  s1;

情况七:

type = all;  全表查询,没用到索引
select  *  from  s1;

注:关于全表查询和使用索引查询

主键索引中,最后一层的叶子节点存储了该表中的所有数据,并且所有的叶子节点组成了一个链表
如果查询时,是从该链表头开始查询,依次向后遍历,那么就叫做全表查询
如果查询时,是从索引节点开始查询,从而找到叶子节点,那么就叫索引查询

Key:

Possible_keys: 表示可能使用的索引
key:表示真实使用的索引
key_len:表示使用索引长度
具体:看上面案例
rows:表示预估的要扫描的记录数

Extra:

情况一:no tables use 

没有对任何表进行扫描:   explain  select  now();

 情况二:impossible where  

表示 where 后面的条件是根本不成立的     explain  select  *  from  s1  where  1  !=  1;

情况三:using  where 

表示查询根本没有用到索引    explain  select  *   from  s1  where  common_field  =  'a';

情况四:null 

表示我们正常使用索引                 explain  select  *  from  s1  where  key1  =  ' a ' ;

情况五:using index

我们使用了覆盖索引,即:不用回表操作   explain  select  id,key1  from  s1  where  key1  = ' a '; 

情况六:联表查询

从动表采用索引,主动表无索引
explain  select  *  from  s1  inner  join  s2  on  s1.key1  = s2.key1;

情况七: using join buffer 

表示使用了 join  buffer 内存块
explain  select  *  from  s1  inner  join  s2  on  s1.common_field   =  s2.common_field;
我们通过该 SQL 语句发现,该联表操作 从动表 没有任何的索引,只能全表扫描
MySQL为了加快速度,分配一块名叫`join buffer`的内存块

情况八:using  union

使用了两个索引    explain  select  *  from  s1  where  id  =  16544  or  key1  = 'a';

情况九:using filesort 

在内存或磁盘中排序,无法利用 B+Tree 索引排序
explain  select  *  from  s1  order  by  common_field  =  'a';

情况十:using  temporary 

使用临时表   explain  select  key1  from key1  union  select  key1  from s2;

你可能感兴趣的:(MySQL,mysql,数据库,database,sql)