Explain的主要属性有id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra。比较重要的属性有id、type、key、rows、Extra。


一、
id属性:其实就是显示了SQL的执行顺序。
1:id相同的情况。执行顺序由上到下。
2:id不同的情况。根据id优先级来看,优先级越高(id值越大)越先执行。
3:id相同不同同时存在。这种是比较特殊的情况,不过还是按照优化先看,然后id相同的情况,还是按照从上到下的情况看。


二、
select_type属性:就是查询的类型,用来区别普通查询、联合查询(union)、子查询等复杂查询,属性分为以下几种。
(1)Simple
简单select查询,查询中不包括子查询、联合查询等。
(2)PRIMARY
PRIMARY可以理解为主查询,当然是在包括子查询等情况下面,最外面的查询被称之为PRIMARY查询。
(3)SUBQUERY
SUBQUERY就是子查询,一般用于select后面或者where条件后面。
(4)DERIVED
DERIVED是衍生查询,一般用于from后面查询返回一个衍生表。
(5)UNION。
UNION是联合查询,UNION或者UNION ALL关键字后面的查询表查询都被标记为联合查询。
(6)UNION RESULT
UNION RESULT就是从union获取的查询结果。


三、
table属性:很显然这个属性就是显示查询数据是关于哪张表的。


四、
type属性:表示MySQL找到数据行采取的方式,也称之为访问方式,显示了查询使用了何种类型。
常用的访问类型排序,从最好到最差的依次是:system > const > eq_ref > ref > range > index > All
一般来说,查询至少得达到range级别。
(1)system
表只有一条记录的情况,显示type为system,这种一般在系统表才会出现,是const的一种特例。
(2)const
const常量,一般用于where条件后面,用于比较主键索引或者唯一索引,索引一次就可以找到一条记录,一般返回一个常量。
(3)eq_ref
唯一性索引扫描,一般是主键Primary key或者唯一索引(union index),只返回一条记录与之匹配。
(4)ref
非唯一性索引扫描,也是一种索引访问,不过符合的记录有多条。
(5)range
索引返回扫描,一般来说在where条件出现了between或者<、>、in等符合或者关键字就是索引访问扫描,不过建了组合索引,有些情况是会导致索引失效的。
(6)index
index也就是索引全扫描(full index scan),index和all的区别是:index扫描所有索引,all扫描所有数据,在mysql中,索引文件是比文件小,所以index扫描性能是比all好的。
(7)all
全表扫描,不建索引的情况,经常出现全表扫描(full table scan)。


五、
possible_keys属性:用于显示理论上扫描可能用到的索引。
key属性:用于显示实践上用到的索引,返回null表示没用到索引。
key_len属性:表示索引使用的字节数,key_len显示的是索引字段最大的可能长度,并非实际使用的长度。
ref属性:ref属性用于显示哪些常用或者列被用于查找索引,前提条件是走索引的。
rows属性:rows数据是根据统计信息及索引选用情况,大致估算出的记录数。


六、
Extra属性:Extra可以理解为拓展或者额外的属性,包含了不在其它属性的信息,但是十分重要的额外信息,常用于分析定位性能问题,比较重要的属性有using filesort、using temporary、using index。
(1)Using filesort
无法利用索引完成排序order by,而选择了文件排序,这种情况是比较耗性能的,所以要看看索引失效的原因。
(2)Using temporary
使用了临时表保存中间结果,出现原因是在对查询结果排序时使用了临时表,常见与order by和group by一起用的情况。
(3)Using index
出现覆盖索引(Covering index),是效率不错的!意思是查询时,数据只要从索引获取就可以(从叶子节点获取),不需要读取数据行。如果using where也一起出现,说明索引被用来查询,只有一个说明只用来读取数据。
注意:查询时,要使用索引覆盖,就要select的列表只取需要的列就可以,不可以select *,如果将所有的字段一起做索引会导致索引文件过大,影响查询性能。
(4)Using where
使用了where过滤条件。
(5)Using join buffer
使用了连接缓存,也就是内外连接。
(6)Impossible where
where子句的查询结果总是false,不能用来获取任何元组。
(7)Select table optimized away
在没有group by子句的情况下,基于索引优化min/max操作或对于MyISAM存储引擎优化count(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段就完成优化了。
(8)Distinct
使用了distinct操作,在查到对一条记录后,就不查找相同的记录。