一、 获取方法与阅读顺序
1. 获取方法
注意这个执行计划只是预估的
explain sql语句
--或者
desc sql语句
2. 阅读顺序
- id值相同:从上往下顺序执行(下图为 tc -> c -> t)
一般越小或者返回值越少的表会越先被执行,这样才能保证后面关联时外层查询结果尽量小,内层查询被循环次数少
- id值不同:越大越先执行(下图为 c -> t -> tc)
- id有相同有不同:规则不变,先看id大的,id相同的从上往下看(下图为 c -> tc -> t)
二、 执行计划各字段详解
1. select_type
常见值如下:
- Primary:主查询,sql中的最外层
- Subquery:子查询
- Simple:不含子查询及union
- Derived:衍生查询,查询时用到了临时表
例如,Form子查询中只有一张表,可以看到id=1的table部分是临时表<Derived2>,其中的2是指id=2的表为衍生表
再如,Form子查询中有两张表且使用了union,则左表就是Derived表,右表为union
- Union与union result,参考上例
2. Table
该步用到的表,也可能是Derived表或者union,参考上例
3. Type
查询(索引)类型。常见含义及性能排序为:System(理想情况)>const(理想情况)>eq_ref(理想情况)>ref>range>index>all,除了all之外其他type均要求表有索引。
- System:只有一条数据的系统表,或衍生表只有一条数据的主查询
- Const:通过主键或唯一索引查询返回一条数据
- eq_ref:对于每个索引键的查询返回匹配的唯一行数据(即返回值无重复,常见于主键和唯一性索引)
- Ref:对于每个索引键的查询返回匹配的任意行数据(1除外,1就是eq_ref)
- Range:索引范围扫描,where后面是一个范围查询
- Index:索引全扫描,相当于SqlServer index scan
- All:全表扫描
4. possible_keys
表有多个索引时,该查询可能用到的索引,预测值,不一定准(例如下面第一个图的例子就不准)
5. key
实际用到的索引,null就是没用索引
6. Key_len
索引的长度,常用于判断复合索引是否完全被使用(条件完全一致)。如果索引字段可为null,会使用1个字节用于标识;若是可变长度varchar,会使用2个字节用于标识。
7. Ref
指明当前表参照的字段(关联或where条件的过滤值),若参照值为常量,则为const。注意字段必须有索引才会有值,否则会为null,例如下面c表tid没有索引时,ref为null。
添加索引后则为t.tid,即其参照的列
8. Rows
使用索引预估查询到的行数,不一定准。
9. Extra
备注信息,查询是否用到了文件排序、临时表、覆盖索引,是否需要回表等,有值时建议关注。
- Using filesort:sql需要额外的排序(查询),where和order by不是同一字段会出现。单列索引建议where哪些字段就order by哪些字段;复合索引建议只使用左前缀列
若使用复合索引,where与order by间不能跨列,也不能不用先导列
只使用左前缀列,可以避免排序
- Using temporary:用到了临时表,常见于group by
- Using index:覆盖索引,不需回表,一般较高效
如果有where条件,索引会出现在key和possible_keys中;如果没有where条件,索引只会出现在key中
- Using where:需要回表查询,Using index和Using where可以同时出现(例如上例图1,因为条件是or,a1字段不需回表但a2需要回表)
- Impossible where:where中条件永假
- Using join buffer:使用连接缓存,一般sql性能有问题
例如最开始那个例子,三个表都没有索引,可能会把值放入内存中然后进行join
标签:ref,查询,索引,计划,MySQL,Using,执行,where,id From: https://blog.51cto.com/u_13631369/6203154