0%

执行计划

执行计划

如果不知道执行计划,那就不可能进行SQL优化,那么执行计划是什么呢?

使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL的,进而分析性能瓶颈

用起来其实很简单,使用explain + sql语句即可

1
explain select * from user;

重点是如何分析结果

1
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |

这写就是所打印出来的字段,接下里就一个个地分析一下是什么意思

id字段

表示的含义:select查询的序号,表示查询中执行select子句或者操作表的顺序

id有三种情况

第一种情况:id相同

id相同

id相同的情况下,是按照table的顺序从上到下开始操作的

第二种情况:id不同

id不同

id不同的情况下,**id越大优先级越高,id大的先被执行**

第三种情况:id相同和不同

id相同不同

先执行id大的,id相同的顺序执行

select_type字段

该字段来表示查询类型,用于区分普通查询、联合查询、子查询等复杂查询常用的有六种

  • SIMPLE 简单查询,不包含子查询和联合查询
  • PRIMARY 如果包含子查询,该类型表示最外层查询
  • SUBQUERY 如果包含子查询,该类型表示内层查询
  • DERIVED 如果在from列表中包含了子查询会被标记为DERIVED,mysql会递归执行这些子查询,并将结果放在临时表中
  • UNION 联合查询如果用来关联两个select的话为UNION,如果UNION包含在from子句中,则外层select为DERIVED
  • UNION RESULT 从UNION表获取结果的select

table字段

显示数据是哪张表的

type字段

检索的类型

从最好到最差依次为

system>const>eq_ref>ref>range>index>ALL

至少要达到range级别,最好能是ref

  • system 表中只有一行数据
  • const 通过一次索引就可以找到(如使用主键查询或unique索引)
  • eq_ref 唯一性索引扫描,对于每个索引键,表中只有一条与之匹配(如使用主键或者unique索引)
  • ref 非唯一性索引扫描,匹配返回某个单独值得所有行
  • range 检索指定范围的数据,使用索引,where语句中使用between…and、in、<、>等
  • index full index scan,全索引扫描,与all相比,index只遍历索引树
  • all 全表扫描

possible_keys字段

查询使用的条件可能涉及到多个字段,所对应的多个索引,但是实际不一定会使用到所列出来的索引

key字段

查询实际使用到的索引

key_len字段

索引中使用的字节数,在不损失精度的情况下,长度越短越好(为索引值的最大可能长度,并非索引实际长度,是根据表结构计算得出,而非数据)

ref字段

显示索引的哪一列被使用了

rows字段

估算出找到需要的数据需要读取的行数

extra字段

表示一些额外信息

  • using filesort 文件排序,mysql无法利用索引来完成的排序,则使用文件排序(出现此种情况,最好进行优化)
  • using temporary 使用了临时表保存中间结果,常见于排序和分组查询(出现此种情况,尽快优化,速度极慢),使用group by分组查询时,最好按照索引顺序来进行分组
  • using index 表示相应的select行使用了覆盖索引(覆盖索引为查询结果为索引列,不必读取数据行),防止访问数据行,速度提升
  • using where 表示使用索引进行检索
  • using join buffer 使用join缓存
  • impossible where where条件总是false,无法查到数据