在MySQL中,当需要对某条SQL查询语句进行分析时,我们经常会使用 explain 命令 或 desc 命令进行操作,分析SQL语句时,explain 和 desc 的作用是一样的。
使用 explain 命令可以分析出SQL查询语句中索引的使用情况、扫描的行数、扫描的类型等等,以便帮助我们对索引和SQL语句进行优化。
使用方法:在SQL查询语句前面,加上 explain 或 desc 即可。
为了便于演示,现在我创建了一张people表:
create table people ( id int unsigned not null auto_increment primary key comment '主键id', last_name varchar(20) not null default '' comment '姓', first_name varchar(20) not null default '' comment '名', birthday date not null default '1970-01-01' comment '出生日期', gender tinyint unsigned not null default 3 comment '性别:1男,2女,3未知', key(last_name, first_name, birthday) ) engine=innodb default charset=utf8;可以看出,people表中有一个主键索引(id)和一个复合索引 key(last_name, first_name, birthday)。
people表中也已经插入了如下一些数据:
idlast_namefirst_namebirthdaygender1 Clinton Bill 1970-01-01 3
2 Allen Cuba 1960-01-01 3
3 Bush George 1970-01-01 3
4 Smith Kim 1970-01-01 3
5 Allen Cally 1989-06-08 3
然后,执行下面的语句:
explain select id,first_name from people where id=3 \G结果如下:
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: people type: const possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: const rows: 1 Extra: 1 row in set (0.00 sec)下面,对explain分析结果中的各个参数进行详细说明。
1. idexplain 得到的结果集的id编号,不重要。
2. select_typeselect_type,即SQL查询语句的类型,准确地说,应该是当前的select语句操作table的方式。常见的值有以下几种:
SIMPLE 它表示简单的单表查询,没有union和子查询。
PRIMARY 它表示主表(也就是最外层的表)查询。这个类型通常可以在DERIVED和UNION时见到。
DERIVED 它表示派生表查询,派生表本身不是一个物理表。
DEPENDENT SUBQUERY 它表示子查询。
UNION 它表示 union 语句中的查询。
3. table它表示和当前的输出结果相关的表。
4. typetype 是一个非常重要的参数,也较为复杂,它表示了当前的查询所使用的查找数据行的扫描方式或访问类型。访问类型有很多种,比如:全表扫描、索引扫描、范围扫描、唯一索引扫描、常数引用扫描等等。这里列的这些,速度是从慢到快,扫描的行数也是从多到少。现在,我们就根据这个顺序介绍几个常见的扫描方式:
ALL 全表扫描,表示需要扫描整张表,才能获取到需要的数据。不会使用到索引,一般来说,它的性能最差。如:
desc select id,first_name from people where gender=2;
index 索引扫描,表示仅从索引中扫描获取数据,index 和 all 差不多,都需要扫描全部的记录,只不过 index 是从索引中扫描全部记录获取需要的数据。虽然从索引中扫描获取了数据,但实际上并没有用到索引加快查找速度的功能。也就是说索引失效了。性能也较差。如:
explain select id,last_name,first_name,birthday from people where first_name='Cuba';