mysql - explain

explain + 查询语句,会返回mysql处理sql语句的分析结果mysql

 

EXPLAIN 
SELECT t1.t_id FROM table1 t1 WHERE t1.t_id = (SELECT MIN(t_id) FROM table2)
UNION 
SELECT t3.t_id FROM table3 t3

 

结果:sql

  

 

 1.id: 表的读取顺序缓存

表明优先级,数字越大,先被加载性能

 

2.select_type : 数据读取操做的操做类型测试

simple  简单查询,没有复杂结构优化

primary  有子查询时,最外层的是primaryspa

subquery   子查询3d

derived      衍生的,通常会出如今from 后面跟select 时(嵌套查询)。code

union                   union查询后面的table会被标记为unionblog

union result         union 查询的结果

 

3. table:   表名

 

4. type:访问类型

性能从好到差依次是:

1. system(系统类型:单行数据,const的特例,等于系统表,基本见不到)   = =不过我测试的时候就算一条数据也达不到system。。。

2. const   (常量类型:利用 主键,或者union index)

3. eq_ref (惟一索引 (union index) 扫描,只有一条记录匹配。)

4. ref       (单行非惟一索引 (index) 扫描)

5. range  (索引或者主键给定范围的查询 好比  select * from table1 where id > 1)

6. index  (全索引扫描)

7. ALL    (全表扫描)

正常状况下,尽可能达到 ref 或者 range 级别已经能够知足大部分需求。

 

5. possible_keys 

 显示理论上可能应用在此次查询的索引(有可能possible_keys是null,而key有值,好比 select id from table1,查询的字段正好是索引,理论上不须要用到索引,可是mysql运行时用到了索引)

 

6. key 

 mysql实际查询时使用到的索引(null则为没有使用索引)

 

7. key_len 

使用到的索引的最大长度(只是mysql推测,不是实际长度),越小越好。

通常条件越多,key_len越大 。

 

8. ref 

索引被用来匹配了那些内容。cont是指常量 好比 id = 1 这种  

若是有用到其余列则会显示匹配用到的列

 

 

 

9. rows 

mysql估算的有多少行须要被扫描。(越小越好)

 

10. Extra

额外信息:

1. using filesort:使用了外部索引排序,mysql没法利用索引完成排序(说明在此次查询中包含了索引字段,可是索引没有被实际用到,最好优化一下)

2. using temporary: mysql完成查询时用到了临时表。

这两种最多见状况,是group by 后的字段顺序和内容跟复合索引不一致。

建一个表和索引用来测试:

CREATE TABLE index_test(
   t_id INT PRIMARY KEY,
   key1 INT,
   key2 INT,
   key3 INT,
   key4 INT
);

INSERT INTO index_test VALUES(1,1,1,1,1);
INSERT INTO index_test VALUES(2,1,2,3,4);
INSERT INTO index_test VALUES(3,4,1,2,3);
INSERT INTO index_test VALUES(4,3,4,1,2);
INSERT INTO index_test VALUES(5,2,3,4,1);


CREATE INDEX index_key1_key2_key3_key4 ON index_test(key1,key2,key3,key4);

 

 

 缘由:由于复合索引按照key1,key2,key3,key4的顺序进行了排序,直接用key3时,mysql虽然想用索引可是没有办法找到

好比 key1 = 4, key2 = 1, key3 = 2 在索引中在 key1 = 3, key2 = 4, key3 = 1 前面,mysql就没法利用索引快速定位 key3位置。

 

优化办法: 把索引顺序和字段可以对应上

 

 

 

3. using index: slq语句使用了覆盖索引,说明此次查询的结果是经过索引直接读取而不是查询到结果再读取结果所在行,效率很高。

好比key1,key2,key3,key4 是复合索引,我查key1,key2,key3,key4的值,mysql直接从这个索引表里读取key1,key2,key3,key4的数据, 而不是先定位 index_test 表中符合条件的列,而后从这个表中读取数据。

 

4. using where: 索引被用于查找(没有直接定位,而是在索引的基础上进行了查找)。

 

当查找的列不全是索引时,就不会有using index了

 

5. using join buffer: join太多,使用了缓存。 

这时能够考虑 配置文件的join buffer调大一点。

 

6. impossible where: where错误,好比下面这种,key1 = 1 and key1 = 2,不可能

 

 

 

7.select tables optimized away:  没有group by时,mysql对count,min,max作了优化。 只是用来讲明。

 

8.   distinct: distinct时第一个结果就符合要求后再也不寻找其余相同值。 只是用来讲明。

 

extra主要做用: 针对1,2种状况,对sql语句进行优化。

 

 

 

11. filtered:   5.5 新加的列, rows扫描的结果中mysql估算有%多少被实际用到

当使用非索引做为查询条件时,遍历了5行,只发现了一个符合结果,只有20%的扫描结果被使用。因此这个值大一些比较好。

相关文章
相关标签/搜索