Explain:你见过这样的Sql吗?( 四 )


文章插图
7、key_len列这一列显示了mysql表示索引中使用的字节数,通过这个值可以算出具体使用了索引中的哪些列,举例来说,user_address的联合索引idx_user_address_id由address_id和user_id两个int列组成,并且每个int是4字节 。通过结果中的key_len=4可推断出查询使用了第一个列address_id来执行索引查询,在不损失精度的情况下长度越短越好 。

Explain:你见过这样的Sql吗?

文章插图
从上图可以看出这个查询用到了idx_user_address_id这个联合索引,这个索引有两个字段,但我们这个查询语句其实就用到了address_id,key_len是4,address_id是int类型,也就是4字节当两个都用到的时候,相应的key_len也就变成了8
Explain:你见过这样的Sql吗?

文章插图
Key_len计算规则如下:
字符串:
Char(n):n字节长度
Varchar(n):如果是utf-8,则长度3n+2字节,加的2字节用来存储字符串长度
数值类型:
Tinyint:1字节
Smallint:2字节
Int:4字节
Bigint:8字节
时间类型:
Date:3字节
Timestamp:4字节
Datatime:8字节
如果字段允许为null,需要1字节记录是否为null
索引的最大长度是768字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来左索引
8、ref显示索引的哪一列被使用了,如果可能的话,是一个常数
这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名(例如:address.id)
9、rows列这一列是mysql估计要读取并检测的行数 ,注意这个不是结果集里面的行数,她只是一个预估值
10、Extra列这一列展示的是额外信息 。常见的重要值如下:
1)using index:使用覆盖索引
覆盖索引定义:mysql执行计划explain结果里的key有使用索引,如果select后面查询的字段都可以从这个索引的树中获取,这种情况一般说用到了覆盖索引,extra里一般都有using index;覆盖索引一般针对的辅助索引,整个查询结果只通过辅助索引就能拿到结果,不需要通过辅助索引树找到主键,再通过主键索引树里获取其他字段值
Explain:你见过这样的Sql吗?

文章插图

Explain:你见过这样的Sql吗?

文章插图
2)using where:使用where语句来处理结果,并且查询的列未被索引覆盖
Explain:你见过这样的Sql吗?

文章插图
3)using index condition:查询的列不完全被索引覆盖,where条件中是一个前导列的范围;
Explain:你见过这样的Sql吗?

文章插图
4)using temporary:mysql需要创建一张临时表来处理查询 。出现这种情况一般是要进行优化的,首先是想到用索引来优化
user.name没有索引,此时创建了临时表来distinct
Explain:你见过这样的Sql吗?

文章插图
address.name建立了idx_name索引,此时查询时extras是using index,没有用临时表
Explain:你见过这样的Sql吗?

文章插图
5)using filesort:将用外部排序而不是索引排序,索引较小时从内存排序,否则需要在磁盘完成排序 。这种情况下一般也是要考虑使用索引来优化的
actor.name未创建索引,会浏览actor整个表,保存排序关键字name和对应的id,然后排序name并检索行记录,
Explain:你见过这样的Sql吗?

文章插图
address.name建立了idx_name索引,此时查询时extra是using index

经验总结扩展阅读