【关于作者】
关于作者,我目前蚂蚁金服搬砖任职,在营销投放领域工作了多年,目前在专注于内存数据库相关的应用学习,如果你有任何技术交流或大厂内推及面试咨询,都可以从我的个人博客(https://0522-isniceday.top/)联系上我~
是什么
查看执行计划
能干嘛
1.表的读取顺序
2.数据读取操作的操作类型
3.哪些索引可以使用
4.哪些索引被实际使用
5.表之间的应用
6.每张表有多少行被优化器查询
执行计划包含的信息
每一条记录大概都能够表示为:
select xxx where xxx,查询类型和查找哪张表
记录的表头信息都是描述这一过程,例如select_type,用到的table,用到的type(检索类型)这些
id
-
(1)id相同,执行顺序由上至下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PHcc51P0-1680445272470)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546278271.png)] -
(2)id不同,子查询的id序号会递增,id值越大越先执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oem2v33V-1680445272471)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546269869.png)] -
(3)id有相同也有不同,id相同则被认为是一组,从上往下执行,id不同则id越大越先执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uytWI10P-1680445272471)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546284121.png)]
select_type
-
Simple
- 简单的select查询,不包含子查询或者union
-
PRIMARY
- 查询中包含若干的子部分,指的是最外层的查询
-
SUBQUERY
- 再select或where中子查询
-
DERIVED
- 在From列表中包含的子查询则被标记为DERIVED,mysql会递归执行这些子查询,把结果放在临时表
-
UNION
- 若第二个select出现在union之后,则被标记为UNION,若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DRIVED
-
UNION_RESULT
- 从UNION表获取结果的Result
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-unh2ylpF-1680445272472)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546295982.png)]
table
- 显示这行数据来自那张表
- DERIVED+[序号],这个序号指代是id,代表这个表示有id=序号所产生的临时表
type
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2yFDF7uF-1680445272472)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546328285.png)]
显示查询属于哪种类型
-
System
- 表只有一行记录。这是const类型的特例
-
const
- 表示通过索引一次就查到了,用于比较主键索引、唯一索引,因为只匹配一行数据,如果将主键放到where语句中,MySql就能将该次查询转化为常量,其实就是在where中通过主键或唯一索引的列去做等值查询
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WrJEbOoV-1680445272473)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546342104.png)]
- 表示通过索引一次就查到了,用于比较主键索引、唯一索引,因为只匹配一行数据,如果将主键放到where语句中,MySql就能将该次查询转化为常量,其实就是在where中通过主键或唯一索引的列去做等值查询
-
eq_ref
- 唯一性索引,对于每个索引键,表中只有一条记录与其匹配,常见于主键或唯一索引扫描,eq_ref与const的区别在于索引并非唯一索引或主键索引,但是通过一个等值连接一次就查询到一条记录
-
ref
- 非唯一性索引。返回匹配某个单独值的所有行,与eq_ref区别在于我能够够通过一个索引列的固定值查出很多数据,而eq_ref却只能查出一条
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0BzqAnDq-1680445272473)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546352211.png)]
- 非唯一性索引。返回匹配某个单独值的所有行,与eq_ref区别在于我能够够通过一个索引列的固定值查出很多数据,而eq_ref却只能查出一条
-
range
- 只检索给定范围的行,使用一个索引来选择行,key列显示了使用了哪个索引
-
index
- Full index scan,与all的区别在于index类型只遍历索引树,因为索引文件通常比数据文件小,就是说index与all都是读全表,但是index是从索引文件中读取(覆盖索引)
-
all
- 全表遍历
-
一般来说,得保证查询至少到range级别,尽量到ref
possible_keys
- 显示可能应用再这张表上的索引,但是不一定被实际查询所使用
key
-
实际用到的索引,为NULL,则没有使用到索引
-
查询中若使用到了覆盖索引,则该索引仅出现在key列表中
覆盖索引其实也就是指全表扫描使用的是index,因为没有在where后面通过索引列进行筛选,所以possible_key中可能为null,但是key中会出现覆盖索引
-
覆盖索引:索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫 做覆盖索引
在了解覆盖索引之前我们先大概了解一下什么是聚集索引(主键索引)和辅助索引(二级索引)
聚集索引(主键索引):
聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的记录数据。
聚集索引的叶子节点称为数据页,聚集索引的这个特性决定了索引组织表中的数据也是索引的一部分。
辅助索引(二级索引):
非主键索引,叶子节点=键值+书签。Innodb存储引擎的书签就是相应行数据的主键索引值
-
key_len
- 表示索引中使用的字节数,也就是这个字段所定义最大字节数,与实际内容无关,是根据定义计算得来,而不是内容,例如char(4)的长度为13这个长度在不损失精度的情况下,最好越小越好,非空字段会额外存储一个字节
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HE8CNXGF-1680445272474)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546361966.png)]
ref
- 显示索引的哪一列被使用了,用于展示哪些列或常量用于查找索引列上的值,意思其实是在type=ref或req_ref场景下具体用了哪些列或常量被用于索引的=匹配
rows
- 每张表有多少行被优化器查询
extra
不适合再其他列使用,但是十分重要的信息
-
Using filesort
- MySql无法利用索引完成的排序操作称为文件排序
-
Using Temporary
- 使用了临时表保存中间结果,Mysql对查询结果排序时又使用到了临时表,常见于order by和group by
-
Using index
- Using index 代表表示相应的 select 操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错! 如果同时出现 using where,表明索引被用来执行索引键值的查找;如果没有同时出现 using where,表明索引只是 用来读取数据而非利用索引执行查找
-
Using where
- 表明使用了 where 过滤
-
Using join buffer
- 使用了连接缓存
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fjz2WeA1-1680445272474)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546381338.png)]
- 使用了连接缓存
-
impossible where
- where 子句的值总是 false,不能用来获取任何元组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SPQiFfzL-1680445272475)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//image_1617546385981.png)]
- where 子句的值总是 false,不能用来获取任何元组
-
select tables optimized away
- 在没有 GROUPBY 子句的情况下,基于索引优化 MIN/MAX 操作或者对于 MyISAM 存储引擎优化 COUNT(*)操 作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化
-
distinct
- 优化distinct操作,第一个匹配的元素就返回结果
思维导图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xjpGhlgv-1680445272475)(https://zhangyuxiangplus.oss-cn-hangzhou.aliyuncs.com/boke//Explain_1617546433460.png)]