sql执行计划分析

执行计划分析在sql调优中占有举足轻重的地位,通过explain+我们自定义的sql便可得出该sql的执行计划,如下:

我们来分析一下执行计划中比较重要的几列:

id列

它是select的序列号,有几个select就有几个id,并且id的顺序是按select出现的顺序增长的。

id列越大执行优先级越高,id相同则从上往下执行,id为null最后执行。

table列

即对应select的那个表。

type列

这一列表示sql的优化程度,依次从最优到最差分别为:system>const>eq_ref>ref>range>index>all。一般来说,得保证查询达到range级别,最好达到ref。

key列

实际走的索引。

rows列

mysql内部估算的结果数或扫描数。

extra列

这一列展示一些额外信息,重要的信息有以下几个:

1)usingindex:表示使用了覆盖索引(覆盖索引的意思就是只查询索引树上的字段,减少了回表操作,从而提升了速度);

2)usingwhere:使用where语句来处理结果,并且查询的列未被索引覆盖;

3)usingindexcondition:查询的列不完全被索引覆盖,where条件中是一个前导列的范围;

4)usingtemporary:mysql需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想到用索引来优化;

5)usingfilesort:使用普通字段排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序。这种情况下一般也是要考虑使用索引来优化的。

sql在mysql中如何执行

要弄懂这个问题,首先我们要搞清楚mysql的内部结构,如下:

sql执行过程如下:

mysql作为服务端,我们的程序作为客户端通过tcp与mysql保持一个长连接。

mysql把我们的sql作为一个key去缓存中查询(mysql的缓存采用的是lru淘汰算法来实现缓存的淘汰机制的),判断是否缓存命中。

如命中,则直接返回数据;如未命中,则继续下面的流程。

mysql实现了一套语法分析器(c语言写的),通过这个分析器来判断我们sql语法的正确性。

语法正确之后,再通过内部实现的优化器对我们的sql进行一些优化,包括成本cost计算等等(这就是为什么我们觉得某个sql理论上会走索引,但是执行计划显示却没有走索引的原因),最终生成我们sql的执行计划。

当然,我们也可以通过force_index(….)强制走索引。

优化完成之后,会进入mysql内部的执行器,然后通过执行器调用我们这张表对应的存储引擎,比如innodb、 myisam、memory等等。

执行引擎会根据优化器分析出来的结果,也就是通过最优索引去对应的索引树上找到对应的数据,同时进行索引树的维护。