MySQL执行计划

一、概述

执行计划是SQl语句调优的一个重要依据。

MySQL 的 EXPLAIN 命令用于查看SQL语句的查询执行计划。从这条命令的输出结果中就能够了解MySQL优化器是如何执行SQL语句的。

这条命令个虽然并没有提供任何调整意见,但它能够体重重要的信息用来帮助作出调优决策。

MySQL [blog]> explain select * from articles \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: articles
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 197
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)

二、执行计划中每个指标的含义

1、id

id是一组数字,表示查询中MySQL执行操作的顺序。

执行顺序按照id的值从大到小执行。当id值一样时,执行顺序按照从上到下执行。

2、select_type

select_type 表示查询中每个select子句的类型,最常见的值有:simple、primary、derived 和 union。其他可能的值有:union result、dependent subquery、dependent union、uncacheable union、uncacheable query。

(1)simple

查询中不包含子查询、表连接或者union等其他复杂语法的简单查询,最常见。

(2)primary

查询中如果包含任何复杂的子查询,则最外层查询被标记为primary。

(3)subquery

在select或where列表中包含了子查询,该子查询被标记为subquery

(4)derived

在from列表中包含的子查询被标记为derived(衍生),或者说当一个表不是一个物理表时,那么就被称为derived。

(5)union

如果第二个select出现在union之后,则被标记为union,即union中的第二个或后面的查询语句会被标记为union;

若union包含在from子句的子查询中,外层select将被标记为derived

(6)union result

从union表获取结果的select被标记为union result。

(7)dependent subquery

这个select_type 值是为使用子查询而定义的。

3、type

type表示MySQL 在表中找到所需行的方式。常见的类型有以下几种,性能由最差到最好。

all、index、range、ref、eq_ref、const、system、null

(1)all

全表扫描,MySQL将进行全表扫描。

(2)index

索引全扫描,MySQL将遍历整个索引来查询匹配的行,index与all的区别为index类型只遍历索引树。

(3)range

索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行,常见于between、<、>、<=、 >= 的查询。

如果where条件中使用了in,则该列也是显示range。

(4)ref

返回匹配某个单独值的所有行,常见于使用非唯一索引或唯一索引的非唯一前缀进行的查找。

ref还经常出现在join操作中。

(5)eq_ref

唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描,即在多表连接中,使用主键或唯一索引作为连接条件。

(6)const

当MySQL对查询某部分进行优化,并转化为一个常量时,会显示为const。

比如,将主键列或唯一索引列置于where列表中,此时,MySQL就能将该查询转换为一个常量const。单表中最多只有一个匹配行,所以查询非常迅速。

(7)system

表中只有一行数据或者是空表,且只能用于myisam或memory表。

如果是innodb存储引擎,那么type列通常是all或者index。

(8)null

MySQL在优化过程中分解语句,执行时不用访问表或者索引就能直接得到结果

4、possible_keys

possible_keys 表示查询时可能使用到的索引。

5、key

key 显示MySQL在查询中实际使用到的索引,如果没有使用索引,则显示为null。

6、key_len

表示使用到索引字段的长度,可用过该列计算出查询中使用的索引的长度。

此列的值对于确认索引的有效性以及多列索引中用到的列的数目很重要。

1个utf8字符占用3个字节,1个gbk字符占用2个字符,int类型长度为4,varchar类型key_len还要加2,若字段允许为空,则key_len需要加1。

7、ref

ref 表示上述表的连接匹配条件

8、rows

rows 表示MySQL根据表统计信息及索引引用情况,估算的找到结果集所需读取的行数。

9、extra

extra包含不适合在其他列中显示,但却十分重要的额外信息。

(1)using where

表示MySQL在存储引擎收到记录后进行”后过滤“。

如果查询未能使用索引,那么 using where 的作用只是说明 MySQL将用where子句来过滤结果集。

如果查询中用到了索引,那么行的限制条件是通过获取必要的数据之后,处理读缓冲区来实现的。

(2)using temporary

表示MySQL 需要使用临时表来存储结果集。常见于排序和分组查询。

(3)using filesort

MySQL中,无法利用索引完成的排序操作称为”文件排序“。

这是order by语句的结果,可以通过选择合适的索引来改进性能,用索引来为查询结果排序。

(4)using index

这个值重点强调了:只需要使用索引就可以满足查询表的要求,不需要访问表数据,MySQL正在使用覆盖索引。

(5)using join buffer

这个值强调了:在获取连接条件时,没有使用索引,并且需要连接缓冲区来存储中间结果。

如果出现了这个值,那应该注意,根据查询的具体情况添加索引来改善性能。

(6)impossible where

这个值强调了:where语句会导致没有符合条件的行

(7)select tables optimized away

这个值意味着:仅通过使用索引,优化器可能金聪聚合函数结果中返回一行

(8)distinct

这个值意味着:MySQL在找到第一个匹配的行之后就会停止搜索其他

(9)index merges

当MySQL决定要在一个给定的表上使用超过一个索引的时候,index merges 就会出现,用来详细说明使用的索引以及合并的类型。

(10)filtered

filtered 给出了一个百分比的值,和rows搭配使用。

(11)partitions

表示给定表所使用的分区