explain的用法
语法
explain+SQL语句
explain select * from tableName;
执行结果:
参数含义
- id:编号
- select_type:查询类型
- table:表
- type:类型
- possible_keys:预测用到的索引
- key:实际使用的索引
- key_len:实际使用的索引的长度
- ref:表之间的引用
- rows:通过索引查询到的数据量
- Extra:额外的信息
参数剖析
(1)id
- id值相同的情况下
按照从上往下的顺序执行。
顺序取决于表数据的多少,数据越多,顺序越靠后,因为程序在执行时,过程中占用的内存越少越有利。
- id值不同的情况下(存在于子查询的情况中)
当id值不同的时候,id值越大,越优先查询。
从SQL中可以看到,C表作为最小的查询基础,别的表都依赖C表查询结果,因此C表的优先级最高。
(2)select_type
- PRIMARY:包含子查询SQL中的 主查询(最外层)
- SUBQUERY:包含子查询SQL中的 子查询(非最外层)
- SIMPLE:简单查询(不包含子查询、union)
- DERIVED:衍生查询(使用到了临时表)
a.在from子查询中只有一张表
b.在from子查询中,如果有table1 union table2,则table1就是derived,table2就是union
(3)table 表名
(4)type 索引类型
system>const>eq_ref>ref>range>index>all(越往左,查询效率越高)
system,const,re_ref很难实现,因此优化目标为ref和range。
- system:只有一条数据的系统表 或者衍生表只有一条数据的主查询。
- const:仅仅能查到一条数据的SQL,用于Primary key或unique索引(类型与索引类型有关)
- eq_ref:唯一性索引,对于每个索引键的查询,返回匹配唯一行数据(有且只有1个,不能多不能少)
- ref:非唯一性索引,对于每个索引键的查询,返回匹配的所有行(0个或多个)
- range:检索指定范围的行,where后面是一个范围查询(between,><=,特殊地,in有时候会失效,从而变成all)
select * from teacher t where tid in (1,2);
select * from teacher t where tid < 3;
- index:查询全部索引中的数据,只需要扫描索引,不需要全部扫描。
- all:查询所有表中的数据,需要把数据全部扫描。
(5)possible_keys 可能用到的索引
(6)key 实际用到的索引
(7)key_len 索引长度
用于判断复合索引是否被完全使用。
建表语句:
create table test_k1
(
name char(20) not null default ''
);
给char类型添加索引:
alter table test_k1 add index index_name(name);
查看索引情况:
explain select * from test_k1 where name=''; ——key_len=60
在UTF-8中,一个字符占3个字节。
考虑字段可以为null的情况:
增加一列name1:
alter table test_k1 add column name1 char(20); ——name1可以为null
给name1加上索引:
alter table test_k1 add index index_name1(name1);
查看索引情况;
explain select * from test_k1 where name=''; ——key_len为61
如果索引字段可以为null,则会用1个字节用于标识。
添加varchar类型字段(可以为null)
alter table test_k1 add column name2 varchar(20);
给varchar类型加索引:
alter table test_k1 add index name2_index(name2);
查看索引情况:
explain select * from test_k1 where name2=''; ——key_len=63
20*3=60+1(null)+2(2个字节 标识可变长度)=63
(8)ref:指明当前表所参照的字段
如下图所示,t表参照的是常量tw,c表参照的是t表的tid。
(9)rows:被索引优化查询的 数据个数
(10)Extra
- using where
- using filesort:出现则说明查询效率较低。
对于单值索引,一般是排序字段和索引字段不是同一个字段。如下所示。
explain select * from test02 where a1='' order by a2; ——using filesort
对于复合索引,一般是排序字段和索引字段出现跨列使用。如下所示。
添加复合索引:
alter table test03 add index idx_a1_a2_a3(a1,a2,a3);
查看索引情况:
exloain select * from test02 where a1='' order by a3; ——using filesort
查看索引情况:
exloain select * from test02 where a2='' order by a3; ——using filesort
- using temporary:性能损耗大,用到了临时表,一般出现在group by语句中。
查a1,按照a1排序:
explain select a1 from test02 where a1 in ('1','2','3') group by a1; ——正常
查a1,按照a2排序:
explain select a1 from test02 where a1 in ('1','2','3') group by a2; ——using temporary
- using index:索引覆盖,性能提升。
- using where:需要回表查询,既查询索引表,又查询原表。
- impossible where:where的条件永远不可能满足。
教程目录
SQL优化教程01-MySQL分层
SQL优化教程02-SQL解析
SQL优化教程03-B树和索引
SQL优化教程04-explain的用法
SQL优化教程05-优化案例1单表查询
SQL优化教程06-优化案例2多表查询
SQL优化教程07-避免索引失效的原则
SQL优化教程08-SQL排查
SQL优化教程09-锁机制