Explain 说明
explain SELECT * FROM tb_category_report;
- id:SELECT识别符,这是SELECT查询序列号。
- select_type:表示单位查询的查询类型,比如:普通查询、联合查询(union、union all)、子查询等复杂查询。
- table:表示查询的表
- partitions:使用的哪些分区(对于非分区表值为null)。
- type(重要)表示表的连接类型。
- possible_keys:此次查询中可能选用的索引
- key:查询真正使用到的索引
- key_len:显示MySQL决定使用的索引size
- ref:哪个字段或常数与 key 一起被使用
- rows:显示此查询一共扫描了多少行,这个是一个估计值,不是精确的值。
- filtered: 表示此查询条件所过滤的数据的百分比
- Extra:额外信息
select_type
- simple: 普通查询,表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple。
explain select * from tb_seckill_goods;
- primary: 查询的主要部分,一个需要union操作或者含有子查询的select位于最外层的单位查询的select_type即primary。
#包含Union 前面的为主要查询
explain select * from tb_seckill_goods a union select * from tb_seckill_goods b;
#包含子查询外层的查询为主要查询
explain select (select id from tb_seckill_goods where price=4.00) from tb_spu;
- union:连接查询
- derived,在from列表中包含的子查询被标记为derived(衍生),MySQL会递归执行这些子查询,把结果放在临时表中
#from中写子查询那么这个子查询会被标记为derived
explain select * from (select * from tb_seckill_goods a union select * from tb_seckill_goods b) c;
- union,若第二个select出现在union之后,则被标记为union:若union包含在from子句的子查询中,外层select将被标记为:derived
explain select * from (select * from tb_seckill_goods a where item_id = '1' union select * from tb_seckill_goods b where item_id = '12' ) c;
- union result 从union表获取结果的select
- dependent union: 依赖连接查询,与union一样出现在union 或union all语句中,但是这个查询要受到外部查询的影响
explain select * from tb_seckill_goods a where a.id in (select id from tb_seckill_goods b union select id from tb_seckill_goods c);
- subquery: 子查询,除了from字句中包含的子查询外,其他地方出现的子查询都可能是subquery
explain select (select id from tb_seckill_goods where price=4.00) from tb_spu;
- dependent subquery: 依赖子查询,与dependent union类似,表示这个subquery的查询要受到外部表查询的影响
explain select * from tb_seckill_goods a where a.id in (select id from tb_seckill_goods b union select id from tb_seckill_goods c);
- derived:派生表, from字句中出现的子查询,也叫做派生表,其他数据库中可能叫做内联视图或嵌套select
#from 中写子查询那么这个子查询会被标记为derived
explain select * from (select * from tb_seckill_goods a union select * from tb_seckill_goods b) c;
type
性能从好到差:
system
const
eq_ref
ref
fulltext
ref_or_null
unique_subquery
index_subquery
range
index_merge
index
ALL
- system:表中只有一行数据或者是空表。等于系统表,这是const类型的特列,平时不会出现,可以忽略不计
- const(重要):使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描。
- eq_ref(重要):唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。
- ref(重要):非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。
- 组合索引
- 非唯一索引
- fulltext:全文索引检索,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引.
- ref_or_null:与ref方法类似,只是增加了null值的比较。实际用的不多。
- unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值
- index_subquery:用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。
- range(重要):索引范围扫描,常见于使用>,<,is null,between ,in ,like等运算符的查询中。
- index_merge:表示查询使用了两个以上的索引,最后取交集或者并集,常见and ,or的条件使用了不同的索引,官方排序这个在ref_or_null之后,但是实际上由于要读取所有索引,性能可能大部分时间都不如range
- index(重要):select结果列中使用到了索引,type会显示为index。全部索引扫描,把索引从头到尾扫一遍,常见于使用索引列就可以处理不需要读取数据文件的查询、可以使用索引排序或者分组的查询。
- all(重要):这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。
- type为const
使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。
explain select * from tb_seckill_goods where id = 1;
- eq_ref:唯一性索引
连接字段主键或者唯一性索引
explain select * from tb_seckill_goods a left join tb_seckill_goods b on a.id=b.id;
- ref:非唯一性索引
非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。
explain select * from tb_seckill_goods where title= '华为5G手机';
- range:范围查询
explain select * from tb_seckill_goods where title like '华为%';
- index:查询结果列中使用索引
select结果列中使用到了索引,type会显示为index。全部索引扫描,把索引从头到尾扫一遍,常见于使用索引列就可以处理不需要读取数据文件的查询、可以使用索引排序或者分组的查询(也就是覆盖索引不用回表查询)。
explain select title from tb_seckill_goods;
- all:全表扫描
这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。
Extra
01-Using filesort
使用了文件排序,说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为“文件排序”。这种操作需要优化sql。
explain select price from tb_seckill_goods where price >100 order by cost_price;
#有索引使用了所以排序
explain select price from tb_seckill_goods where price >100 order by price;
02-Using index
表示相应的SELECT查询中使用到了索引,避免访问表的数据行,这种查询的效率很高!
- 如果同时出现Using Where ,索引在where之后,用作查询条件(也就是说没有没有在where条件中使用到索引)
- 如果没有同时出现Using Where ,索引在where之前,用作查询结果读取(也就是说我们在取列数据的时候和条件过滤的时候都用到了索引)
03-Using where
表示MySQL将对InnoDB提取的结果在SQL Layer层进行过滤,过滤条件字段无索引;
04-Using join buffer
表明使用了连接缓存,比如说在查询的时候,多表join的次数非常多,那么将配置文件中的缓冲区的join buffer调大一些。