MySQL的explain详解

通过explain可以返回的执行计划信息,从而使我们可以知道sql具体的计划执行情况,例如查询的行叔叔,索引使用情况等,从而能够优化我们的sql。

在 select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询时,会返回执行计划的信息,而不是执行这条SQL。

示例:

mysql 复制代码
explain select * from user

上面的语句会返回很多字段,下面一一解读,其中需要重点看的是type、key、rows。

  1. id

MySQL 会为每个 select 语句分配⼀个唯⼀的 id 值。

并且id的顺序是按 select 出现的顺序增长的。 id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。

  1. select_type

查询的类型,根据关联、union、⼦查询等等分类,主要有如下几种:

  • simple:简单查询,不包含子查询或union等;
  • primary:复杂查询,最外层的查询。意思就是该查询语句包含子查询等操作,然后最外面的那个最大的select,就称之为复杂查询;
  • subquery:子查询,指在select语句里面的子查询;
  • derived:衍生查询,这个是在from语句后面的查询语句,MySQL会将结果存放在一个临时表中,也称为派生表;
  • UNION:若第二个SELECT出现在UNION之后,则被标记为UNION;若UNION包含在FROM自居的子查询中,外层SELECT被标记为DERIVED;
  • UNION RESULT:从UNION表获取结果的SELECT。
  1. table

表示 explain 的⼀⾏正在访问哪个表。

  1. type

最重要的列之⼀。表示关联类型或访问类型,即 MySQL 决定如何查找表中的⾏。

主要有如下几种类型:

  • system:当表仅有⼀⾏记录时(系统表),数据量很少,往往不需要进⾏磁盘 IO,速度⾮常快。
  • const:表示查询时命中 primary key 主键或者 unique 唯⼀索引,或者被连接的部分是⼀个常量值。这类扫描效率极⾼,返回数据量少,速度⾮常快。
  • eq_ref:primary key 或 unique key 索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录。
  • ref_or_null:这种连接类型类似于 ref,区别在于 MySQL 会额外搜索包含 NULL 值的⾏。
  • index_merge:使⽤了索引合并优化⽅法,查询使⽤了两个以上的索引。
  • unique_subquery:替换下⾯的 IN ⼦查询,⼦查询返回不重复的集合。
  • index_subquery::区别于 unique_subquery ,⽤于⾮唯⼀索引,可以返回重复值。
  • range:使⽤索引选择⾏,仅检索给定范围内的⾏。简单点说就是针对⼀个有索引的字段,给定范围检索数据。在 where 语句中使⽤ bettween...and 、 < 、 > 、 <= 、 in 等条件查询 type 都是 range。
  • index:: Index 与 ALL 其实都是读全表,区别在于 index 是遍历索引树读取,⽽ ALL 是从硬盘中读取。
  • ALL:全表扫描。

性能从最优到最差分别为:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge >

unique_subquery > index_subquery > range > index > ALL

  1. possible_keys

显示查询可能使⽤哪些索引来查找,使⽤索引优化 sql 的时候⽐较重要。

  1. key

这⼀列显示 mysql 实际采⽤哪个索引来优化对该表的访问,判断索引是否失效的时候常⽤。

  1. key_len

这一列显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。

  1. ref

ref 列展示的就是与索引列作等值匹配的值,常⻅的有:const(常量),func,NULL,字段名

  1. rows

估算 SQL 要查到结果集需要扫描读取的数据⾏数,这个值⾮常直观显示 SQL 的效率好坏,原则上 rows 越少越好。

  1. Extra

额外信息,里面也有⼀些重要的信息:

  • Using index:表示 MySQL 将使⽤覆盖索引,以避免回表。
  • Using where:表示会在存储引擎检索之后再进⾏过滤,其实也就是没有使用到索引,用的是全表扫描。
  • Using temporary :表示对查询结果排序时会使⽤⼀个临时表。
相关推荐
狂炫冰美式13 分钟前
人均配了AI, 为什么公司还是没变快? 🤔 本质还是分布式系统问题
前端·后端·架构
ClouGence2 小时前
SQL Server CDC 能放到 Always On 备库读吗?一文讲透原理与实践
数据库·sql server
她的男孩2 小时前
Spring Boot 接 Flowable 工作流:用 3 个注解搭一个请假审批流程
java·后端·架构
爱读源码的大都督2 小时前
Claude Code源码分析(三):为什么系统提示词中需要有tools呢?
前端·人工智能·后端
爱勇宝2 小时前
Claude Code 被曝暗藏“隐形检测”代码:封代理不是最可怕的,可怕的是你根本不知道它在干什么
前端·后端·程序员
ITOM运维行者3 小时前
从零搭建企业级服务器监控体系:踩坑实录与架构设计
前端·后端
用户4099322502123 小时前
Vue状态管理入门第四章:组合式store和SSR风险
前端·vue.js·后端
用户34232323763173 小时前
SPI 通信与高速外设驱动详解
后端
魏祖潇3 小时前
SDD 完整指南——Spec 端打底、Story 端交付、留白区
人工智能·后端
feelmylife594 小时前
消息队列可靠投递与幂等消费 -- 从"消息丢了"到"消息别重复"的完整工程实践
后端