文章目录
- 前言
- 1.id
- 2.select_type
- 3.table
- 4.type
- 5.possible_keys
- 6.key
- 7.key_len
- 8.ref
- 9.rows
- 10.extra
- 总结
前言
本文介绍了mysql 执行计划列说明。
1.id
select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
三种情况
id相同,执行顺序由上至下
id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
id相同不同,同时存在
2.select_type
类型 | 描述 |
SIMPLE | 简单的select查询,查询中不包含子查询或者UNION |
PRIMARY | 查询中若包含任何复杂的子部分,最外层查询则被标记 |
SUBQUERY | 在SELECT或WHERE列表包含了子查询 |
DERIVED | 在FROM列表中包含的子查询被标记为DERIVED(衍生) MySql递归执行这些子查询,把结果放在临时表里 |
UNION | 若第二个SELECT出现在UNION之后,则被标记为UNION; 若UNION包含在FROM子名的子查询中,外层SELECT将被标记为:DERIVED |
UNION RESULT | 从UNION表获取结果的SELECT |
3.table
对应的表名
4.type
优先级从高到低,最好达到range及以上级别
system>const>eq_ref>ref>range>index>ALL
类型 | 描述 |
system | 表只有一行记录,这是const类型的特例,平时不会出现,可以忽略不计 |
const | 表示通过索引一次就找到了,const用比较primary key或者unique索引 。因为为匹配一行数据,所以很快,若将主键置于where列表中,MySQL就能将该查询转换为一个常量 |
eq_ref | 唯一性索引扫描,对于每个索引键,表中只一条记录与之匹配。常见于主键或唯一索引扫描 |
ref | 非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,也可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体 |
range | 只检索给定范围的行,使用一个索引选择行。key列显示使用了哪个索引,一般就是在你的where语句中出现了between、<、>、in等表达式查询,这个种范围扫描索引比全表扫描要好,因为它只需要开始于索引的某一点,不用扫描全部索引 |
index | select查询的字段是索引时,index |
all | Full Table Scan,将遍历全表以找到匹配的行 |
5.possible_keys
列出所有可能用的索引,但只会使用其中1个,也可能实际不使用索引
6.key
实际使用的索引,如果为NULL,则没有使用索引
查询中若使用了覆盖索引,则该索引和查询的select字段重叠
7.key_len
表示索引中使用的字节数,可能过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好
key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通表内检索出的
计算公式举例:varchar(n)变长字段+允许Null=n(utf8=3,gbk=2,latin1=1)+1(NULL)+2*
注:mysql不同版本字节数不同;不同字符编码,字节数不同
8.ref
显示索引的哪一列被使用了,如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值
9.rows
根据统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数
10.extra
类型 | 描述 |
Using filesort | 说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。 MySql中无法利用索引完成的排序操作称为“文件排序” |
Using temporary | 使用了临时表保存中间查询结果,Mysql在查询结果排序时使用临时表。常见于order by 和 group by |
Using index | 是否用了覆盖索引 |
Using where | 表明使用了where过滤 |
Using join buffer | 使用了连接缓存 |
Impossible where | where子句的值总是false ,不能用来获取任何元组 |
总结
本文仅仅简单介绍了mysql 执行计划列说明,而mysql 执行计划的更多优化需要我们继续深耕。