无论是在面试还是平时工作中,mysql调优都是避不开的话题。调优首先要知道sql语句的具体执行过程,就要用到explain关键字来模拟优化器执行SQL查询语句。 mysql官网执行计划介绍
explain用途
explain的用法很简单,就是在一句SQL的select关键字前面加上explain,再执行,就可以得到相对应的结果。通过执行计划,你可以
- 了解复杂sql的执行顺序
- 获取索引的可用信息和实际使用信息
- 哪些查询走了全表扫描,需要优化,进而对比优化后的结果
执行结果字段释义
在命令行执行explain + sql 的结果字段如下图所示,下面依次来解释下各个字段代表的意思(如果有分区表的话还会有partitions)
| Column | Meaning |
|---|---|
| id | The SELECT identifier |
| select_type | The SELECT type |
| table | The table foe the output row |
| partitions | The matching partitions |
| type | The join type |
| possible_keys | The possible indexs to choose |
| key | The index actually chosen |
| key_len | The length of the chosen key |
| ref | The columns compared to the index |
| rows | Estimate of rows to be examined |
| filtered | Percentage of rows filtered by table condition |
| extra | Additional information |
-
id 意为select查询的序列号,包含一组数字,表示查询中执行select字句或操作表的顺序
- id相同,顺序自然自上而下
- id全不同,如果是子查询,id的序号会递增,id数字越大越先执行
- id部分相同,先按数字大的先执行,数字相同的按自上而下顺序执行
-
select_type 查询类型,用于区别普通查询、联合查询、子查询等复杂查询
-
simple
简单的select查询,查询中不包含子查询或union -
primary
查询中包含子查询,最外层查询则标记为primary -
subquery
在select或where中包含子查询 -
derived
在from列表中包含的子查询,也叫派生类,MySQL会递归执行这些子查询,把结果放在临时表里 -
union
若第二个select出现在union之后,则被标记为UNION,若UNION包含在from子句的子查询中,外层select将被标记为DERIVED -
union
result 从UNION表获取结果的select
-
-
table 显示这一行的数据是关于哪张表,内容为表名或者别名,可能是临时表或者union合并结果集
-
type 显示访问类型,表示以何种方式访问了数据,从最好到最差的排列为
system > const > eq_ref > ref > range > index > all
一般情况下,得保证查询至少达到range,最好能达到ref-
system
表里只有一行记录,是const的特例,一般不会出现 -
const
表里至多有一个匹配行 -
eq_ref
唯一性索引扫描 -
ref
非唯一性索引扫描 -
range
利用索引查询的时候限定了范围,一般出现于between <(<=) > (>=) in 等查询 -
index
全索引扫描,比all效率高,index从索引中扫描,而all是从硬盘上扫描 -
all
全表扫描,一般出现此类型的sql并且数据量较大的话就要进行优化
-
-
possible_keys 显示的是可能应用在这张表中的索引,一个或多个,查询涉及到的字段若存在索引,则该索引会被列出,但不一定被查询实际使用
-
key
- 实际使用的索引,如果为null,则没有用到索引
- 若查询中用到了索引覆盖,则该索引和查询的select字段重叠,仅出现在key列表中
-
key_len 表示索引中使用的字节数,可以通过key_len计算查询中使用的索引长度,在不损失精度的情况下长度越短越好
-
ref 显示索引的哪一列被使用了,如果可能的话,是一个常数
-
rows 根据表的统计信息及索引选用情况,大致估算出找到所需记录需要读取的行数
-
extra 包含的额外信息,无法在一个字段中概述但是依旧重要的额外信息
-
using filesort
文件排序意为MySQL无法利用索引进行排序,而使用了外部的排序算法,常见于order by 或 group by -
using temporary
使用了临时表保存中间结果,查询完成后临时表删除 -
using index
索引覆盖意为直接从索引中读取数据,而不用访问数据表,如果同时出现 using where 表明索引被用来执行索引键值的查找,否则,索引被用来读取数据而不是执行查找操作 -
using where
使用where进行条件过滤 -
using join buffer
使用了连接缓存 -
impossible where
where语句结果是false -
select tables optimized away
在没有group by字句情况下,基于索引优化操作或对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化 -
distinct
优化distinct操作,在找到第一匹配的元祖后即停止找同样值的动作
-
本篇文章主要介绍MySQL中explain关键字的用法和结果列的详细释义。