一、explain-性能分析的重要命令
1. 字段解析
1.1 id
id 可以用来分析表的执行顺序,遵循的原则是:id 越大就越先执行,id相同则按照从上到下的顺序执行
1.2 select_type
查询的操作类型,包括以下几种:
- simple
就是简单的查询,不包含任何子查询或者 union。 - primary
如果查询包含子查询,那么最外层的查询就会被标记为 primary。 - subquery
顾名思义,就是子查询。 - derived
衍生表(虚拟表),from 中包含的子查询,会被标记为 derived;mysql 会递归执行这些子查询,并把结果放到临时表中。
另外,table 中的 derived 后会接数字,对应的是id,也就是指明了是由哪个表衍生出来的。 - union
若第二个 select 出现在 union 之后,则被标记为 union;
若 union 包含在 from 子句的子查询中,外层 select 将被标记为 derived。 - union result
从 union 结果集获取数据的 select 会被标记为 union result。
1.3 table
指明这一行数据是关于哪张表的。
1.4 type
访问类型,显示查询用了何种类型,常用类型优劣排序如下:
system > const > eq_ref > ref > range > index > all
- system
单表且只有一行数据(等于系统表),const 类型的特例 - const
通过一次索引就找到数据,const 用于比较主键和唯一,因为数据都是独一无二,经过一次索引即可找到;如将主键放到 where 中,mysql 就能将该查询转换为常量。 - eq_ref
唯一性索引扫描,每个索引建,表中只有一条数据与之匹配。常见于主键和唯一。 - ref
非唯一性索引扫描,返回某个单独值的所有行,和 eq_ref 的区别就是 ref 是返回多行,eq_ref 返回单行。 - range
按照某个给定范围检索,between, >, <, in 等关键字都是范围检索。 - index
全索引扫描,index 和 all 的区别是 index 值遍历加索引树。因为索引文件通话参比数据小,所以 index 通常比 all 快。两者都是扫描全表,只是 index 从索引中读取,而 all 从磁盘中读取。 - all
全表扫描,百万量级需要优化。
1.5 possible_keys,key
- possible_keys
查询涉及到的索引,可能但不一定被用到 - key
实际使用的索引,如果为 null,则说明没有用到索引。
如果使用了覆盖索引,则该索引进出现在 key 列表中
1.6 key_len
表示索引中使用的字节数,可通过该列计算查询中使用的索引长度,在不损失精度的情况下,越短越好。key_len 显示的是索引字段的最大可能长度,并非实际长度,即 key_len 是通过表定义计算而得,不是从表中检索出的。
1.7 ref
指明和索引列有关的字段和常数,用于说明表中的哪一个字段被使用,如果可能的话是一个常数。就是那些列和常量被用到索引的列上。
1.8 rows
根据表统计情况和索引使用情况,大致计算出要找到所需的数据得读取多少行,越小越好
1.9 extra
额外信息
-
using filesort
说明 mysql 会对数据使用一个外部索引排序,而不是按照表内的索引顺序进行读取。mysql 中,无法用索引完成的排序成为“文件排序(filesort)”。
例如,建了索引 idx_a,结果排序用的是 b 字段而不是 a 字段;或者建立了复合索引 idx_a_b,却用 b排序。
这种情况,有了索引却不用,会造成额外负担,应尽量避免。 -
using temporary
使用了内部临时表保存中间结果,排序时又使用了临时表。常见于 order by,group by。
需要从表中查数据推到临时表,再从临时表操作,使用过后还需删除,给 mysql 造成额外负担,应极力避免。 -
using index
使用了覆盖索引(covering index),避免访问数据行,效率较高。
如果同时出现 using where 说明,使用了索引进行索引键值查找,如:在 where 中使用了索引字段;没有 using where,说明索引用来读取数据,如:在 select 中有索引字段。
覆盖索引:或称索引覆盖,select 中的字段只用从索引行中获取,不用读取数据行。就是 select 中的字段可以直接从索引中获取,而不用再通过索引读取数据文件,也就是查询列包含了索引字段。后者说索引中包含了查询所需的数据。
注意:要使用覆盖索引,须避免使用 select *,只查找需要的字段(和索引匹配),因为查找全部字段会导致索引文件过大,降低性能。 -
using where
使用了 where -
using join buffer
join 连接较多,使用了 join 连接缓存,可视情况调整 join buffer -
impossible where
where 中的条件始终为 false,查询条件有误,需整改 -
select tables optimized away
在没有 group by 子句的情况下,基于索引优化 min/max 或者对 MyISAM 存储引擎优化 count(*),不必等到执行阶段才进行计算,而是在查询执行计划生成的阶段即完成优化。 -
distinct
优化 distinct 操作,找到第一个匹配元祖后就停止找同样值得动作
网友评论