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


Explain:你见过这样的Sql吗?

文章插图
8)range:表示利用索引查询的时候限制了范围,在指定范围内进行查询,这样避免了index的全索引扫描,适用的操作符: =, <>, >, >=, <, <=, IS NULL, BETWEEN, LIKE, 或者 IN()
Explain:你见过这样的Sql吗?

文章插图
9)index:全索引扫描这个比all的效率要好 , 主要有两种情况,一种是当前的查询时覆盖索引,即我们需要的数据在索引中就可以索?。蛘呤鞘褂昧怂饕信判颍庋捅苊馐莸闹嘏判?,一般是扫描某个二级索引,这种扫描不会从索引树根节点开始快速查找,而是直接对二级索引的叶子节点遍历和扫描,速度还是比较慢的,这种查询一般为使用覆盖索引,二级索引一般比较小,所以这种通常比All快一些
Explain:你见过这样的Sql吗?

文章插图

Explain:你见过这样的Sql吗?

文章插图
那么这里提出一个问题 , address表中其实有两个索引 , 一个是主键索引 , 一个是二级索引idx_name,那么为什么这里会使用二级索引而不是主键索引呢?
打开address表你会发现 。。Address只有两个字段一个id , 一个name,而idx_name这个索引树中就包含了name和id , 而要查的字段都存在于idx_name索引树中,mysql有一个这样的优化原则 , 凡是我查找结果集的分析我查找出来 , 如果这个结果集的几个字段在我们所有索引里面都有 , 他会优先选择二级索引去查 , 因为二级索引小不管是主键索引还是二级索引都是从叶子节点的第一个开始找 , 遍历到最后一个
11)all:全表扫描,扫描你的聚簇索引的所有叶子节点,一般情况下出现这样的sql语句而且数据量比较大的话那么就需要增加索引来进行优化了 。
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吗?

推荐阅读