explain结果中有一个Extra字段,对分析与优化SQL有很大的帮助
数据准备
create table user (id int primary key,name varchar(20),sex varchar(5),index(name))engine=innodb;insert into user values(1, 'shenjian','no');insert into user values(2, 'zhangsan','no');insert into user values(3, 'lisi', 'yes');insert into user values(4, 'lisi', 'no');
数据说明:
用户表:id主键索引,name普通索引(非唯一),sex无索引;
四行记录:其中name普通索引存在重复记录lisi;
实验目的:
通过构造各类SQL语句,对explain的Extra字段进行说明,启发式定位待优化低性能SQL语句。
一、【Using where】
**
explain select * from user where sex='no';
结果说明:
Extra为Using where说明,SQL使用了where条件过滤数据。
需要注意的是:
(1)返回所有记录的SQL,不使用where条件过滤数据,大概率不符合预期,对于这类SQL往往需要进行优化;
(2)使用了where条件的SQL,并不代表不需要优化,往往需要配合explain结果中的type(连接类型)来综合判断;
本例虽然Extra字段说明使用了where条件过滤,但type属性是ALL,表示需要扫描全部数据,仍有优化空间。
常见的优化方法为,在where过滤属性上添加索引。
画外音:__本例中,sex字段区分度不高,添加索引对性能提升有限。
二、【Using index】 
实验语句:
explain select id,name from user where name='shenjian';
结果说明:
Extra为Using index说明:SQL所需要返回的所有列数据均在一棵索引树上(非主键索引),而无需访问实际的行记录。表示不需要回表,直接可以从索引中获取数据。例如联合索引的部分数据。
三、【Using index condition】
实验语句:
explain select id,name,sex from user where name='shenjian';
结果说明:
Extra为Using index condition说明,索引下推,原本需要在数据查出来之后通过where进行过滤,现在在索引(非主键索引层面就进行过滤),这样回表的时候就不需要把没用的数据再查一次出来了。_
四、【Using filesort】
实验语句
explain select * from user order by sex;
结果说明:
Extra为Using filesort说明,排序字段没有建索引。
五、【Using temporary】
实验语句
explain select * from user group by name order by sex;
结果说明:
Extra为Using temporary说明,需要建立临时表(temporary table)来暂存中间结果。
这类SQL语句性能较低,往往也需要进行优化。
典型的,group by和order by同时存在,且作用于不同的字段时,就会建立临时表,以便计算出最终的结果集。
六、【Using join buffer (Block Nested Loop)】
实验语句
explain select * from user where id in(select id from user where sex='no');
结果说明:
Extra为Using join buffer (Block Nested Loop)说明,需要进行嵌套循环计算。
画外音:__内层和外层的type均为ALL,rows均为4,需要循环进行4*4次计算。
这类SQL语句性能往往也较低,需要进行优化。
典型的,两个关联表join,关联字段均未建立索引,就会出现这种情况。常见的优化方案是,在关联字段上添加索引,避免每次嵌套循环计算。
