MySQL之explain 的type列 & Extra列

2023-10-30

explain 可以分析 select 语句的执行,即 MySQL 的“执行计划。

一、type 列
MySQL 在表里找到所需行的方式。包括(由左至右,由最差到最好):
| All | index | range | ref | eq_ref | const,system | null |
ALL(所有)
全表扫描,MySQL 从头到尾扫描整张表查找行。
mysql> explain select * from a\G
...
         type: ALL
如果加上 limit 如 select * from a limit 100 MySQL 会扫描 100 行,但扫描方式不会变,还是从头到尾扫描。
index(索引)
根据索引来读取数据,如果索引已包含了查询数据,只需扫描索引树,否则执行全表扫描和All类似;  
create table a(a_id int not null, key(a_id));
insert into a value(1),(2);
mysql> explain select a_id from a\G
...
         type: index
range(范围)
以范围的形式扫描索引
建表:
create table a(a_id int not null, key(a_id));
insert into a values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
mysql> explain select * from a where a_id > 1\G
...
         type: range
...
IN 比较符也会用 range 表示:
mysql> explain select * from a where a_id in (1,3,4)\G
...
         type: range
...
`
ref(引用)
非唯一性索引访问
建表:
create table a(a_id int not null, key(a_id));
insert into a values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
mysql> explain select * from a where a_id=1\G
...
         type: ref
...
eq_ref(等值引用)
使用有唯一性索引查找(主键或唯一性索引)
建表及插入数据:
create table a(id int primary key);
create table a_info(id int primary key, title char(1));
insert into a value(1),(2);
insert into a_info value(1, 'a'),(2, 'b');
mysql> explain select * from a join a_info using(id);
...+--------+--------+...
...| table  | type   |...
...+--------+--------+...
...| a      | index  |...
...| a_info | eq_ref |...
...+--------+--------+...
此时 a_info 每条记录与 a 一一对应,通过主键 id 关联起来,所以 a_info 的 type 为 eq_ref。
删除 a_info 的主键:ALTER TABLE  `a_info` DROP PRIMARY KEY;
现在 a_info 已经没有索引了:
mysql> explain select * from a join a_info using(id);
+----+...+--------+--------+...
| id |...| table  | type   |...
+----+...+--------+--------+...
 1 |...| a_info | ALL    |...
 1 |...| a      | eq_ref |...
+----+...+--------+--------+...
这次 MySQL 调整了执行顺序,先全表扫描 a_info 表,再对表 a 进行 eq_ref 查找,因为 a 表 id 还是主键。
删除 a 的主键:alter table a drop primary key;
现在 a 也没有索引了:
mysql> explain select * from a join a_info using(id);
...+--------+------+...
...| table  | type |...
...+--------+------+...
...| a      | ALL  |...
...| a_info | ALL  |...
...+--------+------+...
现在两个表都使用全表扫描了。
建表及插入数据:
create table a(id int primary key);
create table a_info(id int, title char(1), key(id));
insert into a value(1),(2);
insert into a_info value(1, 'a'),(2, 'b');
现在 a_info 表 id 列变为普通索引(非唯一性索引):
mysql> explain select * from a join a_info using(id) where a.id=1;
...+--------+-------+...
...| table  | type  |...
...+--------+-------+...
...| a      | const |...
...| a_info | ref   |...
...+--------+-------+...
a_info 表 type 变为 ref 类型了。
所以,唯一性索引才会出现 eq_ref (非唯一性索引会出现 ref ),因为唯一,所以最多只返回一条记录,找到后无需继续查找,因此比 ref 更快。
const(常量连接)
被称为“常量”,这个词不好理解,不过出现 const 的话就表示发生下面两种情况:
在整个查询过程中这个表最多只会有一条匹配的行,比如主键 id=1 就肯定只有一行,只需读取一次表数据便能取得所需的结果,且表数据在分解执行计划时读取。 返回值直接放在 select 语句中,类似 select 1 AS f 。可以通过 extended 选择查看内部过程:
建表及插入数据:
create table a(id int primary key, c1 char(20) not null, c2 text not null, c3 text not null);
insert into a values(1, 'asdfasdf', 'asdfasdf', 'asdfasdf'), (2, 'asdfasdf', 'asdfasdf', 'asdfasdf');
mysql> explain extended select * from a where id=1\G
...
         type: const
possible_keys: PRIMARY
          key: PRIMARY
...
用 show warnings 查看 MySQL 是如何优化的:
mysql> show warnings\G
...
Message: select '1' AS `id`,'asdfasdf' AS `c1`,'asdfasdf' AS `c2`,'asdfasdf' AS
`c3` from `test`.`a` where 1
查询返回的结果为:
mysql> select * from a where id=1;
+----+----------+----------+----------+
| id | c1       | c2       | c3       |
+----+----------+----------+----------+
 1 | asdfasdf | asdfasdf | asdfasdf |
+----+----------+----------+----------+
可以看出,返回结果中的字段值都以“值 AS 字段名”的形式直接出现在优化后的 select 语句中。
修改一下查询:
mysql> explain select * from a where id in(1,2)\G
...
         type: range
...
当返回结果超过 1 条时, type 便不再为 const 了。
重新建表及插入数据:
create table a (id int not null);
insert into a value(1),(2),(3);
mysql> explain select * from a where id=1\G
...
         type: ALL
目前表中只有一条 id=1 的记录,但 type 已为 ALL ,因为只有唯一性索引才能保证表中最多只有一条记录,只有这样 type 才有可能为 const 。
为 id 加普通索引后, type 变为 ref ,改为加唯一或主键索引后, type 便变为 const 了。
二、Extra 列

Extra表示附加信息,常见的有如下几种(也按查询效率从高到低排列):

  • Using index:表示使用索引,如果只有 Using index,说明他没有查询到数据表,只用索引表就完成了这个查询,这个叫覆盖索引如果同时出现Using where,代表使用索引来查找读取记录, 也是可以用到索引的,但是需要查询到数据表。
  • Using where:表示条件查询,如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则会出现 Using where。如果type列是ALL或index,而没有出现该信息,则你有可能在执行错误的查询:返回所有数据。  
  • Using filesort:不是“使用文件索引”的含义!filesort是MySQL所实现的一种排序策略,通常在使用到排序语句ORDER BY的时候,会出现该信息。  
  • Using temporary:表示为了得到结果,使用了临时表,这通常是出现在多表联合查询,结果排序的场合。

如果EXPLAIN出现后面两个信息(Using filesort,Using temporary),而rows又比较大,通常意味着你需要调整查询语句,或者需要添加索引,总之需要尽量消除这两个信息。



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL之explain 的type列 & Extra列 的相关文章

随机推荐

  • 计算机地址怎么填写,电脑服务器名称或地址怎么填

    使用宽带路由器的话一般建议手工指定电脑的IP地址和DNS等参数 下面学习啦小编为大家整理了电脑服务器名称或地址怎么填写的内容 欢迎参阅 正确填写电脑IP地址和DNS参数名称 如果你使用的是Windows 2000或Windows XP系统
  • ztree自定义图标(iconSkin,iconClose,iconOpen)

    设计图 先放上ztree的api http www treejs cn v3 api php 首先是ztree的初始化 js文件的初始化 var obj name 福建省 id 1 iconOpen openurl iconClose cl
  • 云原生服务无状态(Stateless)特性的实现

    文章目录 为何要使用无状态服务 无状态服务的实现方法 1 会话状态外部化 2 负载均衡 3 自动伸缩 4 容器编排 5 数据存储 6 安全性 示例 使用Spring Boot实现无状态服务 结论 欢迎来到云计算技术应用专栏 云原生服务无状态
  • Java数组(复习)

    Java数组 数组 数组是指一种容器 可以用来存储同种数据类型的多个值 数组容器在存储数据的时候 需要结合隐士转换考虑 例如 int类型的数组容器 可以存储byte short int类型的数组 double类型的数组可以存储 byte s
  • 如何取消edge浏览器最新版,新增标签页的广告呢?

    今天我打开edge浏览器 快乐的写我的代码 突然发现 新建标签页的时候竟然这样 简直气煞我也 我不允许简洁的生活出现这种事 难道我又要换回谷歌 但是谷歌不能在线备份书签 我已经丢了很多次啦 于是我找到了这个 使用edge官方的插件库安装之后
  • 【JavaWeb】练习三

    一 简答题 1 gt 简述servlet的生命周期 第一次访问某个servlet的时候 tomcat容器会创建servlet实例 紧接着会调用init方法进行初始化 然后执行service方法 在父类中的service方法中判断请求是get
  • 从java环境配置到成功使用VOSviewer

    本文的目的是分享如何快速安装和使用VOSviewer B站包括csdn很多信息都是分散的 找资源会浪费很多时间 本文帮助小白快速高效的安装VOSviewer 第一步 下载安装包 下载方法一 如果电脑当中没有配置过java环境 可以参考下面的
  • C# 通过文件结构直接生成xls(Excel)文件

    以下代码演示了 直接通过excel可以识别的文件结构生成xls文件的方法 这样就可以不引用麻烦的ole了 using System using System Collections Generic using System Text nam
  • 安信可ESP32-CAM修改Web网页源代码

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 安信可ESP32 CAM修改Web网页源代码 前言 一 使用CyberChef将数组转义成 HTML 二 使用CyberChef将 HTML转义成数组 参考 前言 安信可ES
  • 毕业设计-基于机器视觉的虹膜图像人眼定位及分类算法-yolo

    目录 前言 课题背景和意义 实现技术思路 一 算法基础 二 EL YOLO模型 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的
  • 两个蓝牙模块HC-05的主从机匹配

    两个蓝牙模块HC 05的主从机匹配 1 HC 05蓝牙模块知识 1 1 两种工作模式 1 2 进入命令响应工作模式 1 3 什么叫做置高一次PIO11 1 4 怎么区分进了命令响应工作模式呢 1 5 串口调试助手发送AT命令格式 2 AT命
  • C#调用Python脚本训练并生成AI模型(以Paddle框架为例)

    目录 一 C 调用通过IronPython语言移植 1 1 IronPython安装 1 2 示例代码 1 3 运行结果 1 4 特点 二 C 调用Python文件打包dll 2 1 步骤 2 1 1 Cython生成python脚本预编译
  • 面试--竞品分析,会随时补充

    面试题 小型竞品分析 对于一般的竞品分析 可以参照产品的五要素 分别从产品的五要素进行分析 战略层 企业和用户对于产品的期望和目标是什么 范围层 产品的功能和内容需求集合 结构层 确定要呈现给用户的选项和呈现模式 及交互设计和信息架构 框架
  • 【计算机视觉

    文章目录 一 分割 语义相关 20篇 1 1 VideoCutLER Surprisingly Simple Unsupervised Video Instance Segmentation 1 2 Compositional Semant
  • es6链判断运算符和null的判断运算符

    链判断运算符 JavaScript在实际编程中 如果读取对象内部的某个属性 往往需要判断一下 需要判断属性的上层对象是否存在 比如 读取 dataList userInfo firstName这个属性 安全的写法是写成下面这样 let da
  • 【微信小程序】小程序之间跳转(路由)参数传递及跳转方式详解和封装

    今天我们来说道说道微信小程序里面当中的几种跳转方式 微信小程序跳转的方式总共有5种 可以对应各种的应用场景 1 wx navigateTo 保留当前页面 跳转到应用内的某个页面 但是不能跳到 tabbar 页面 可封装函数为 跳转新页面页面
  • 项目中没有 requirements.txt

    项目下创建一个文件 autoinstall py 复制下面的代码 在项目最开始加入import autoinstall 直接运行项目即可 import sys import os from importlib import import m
  • 《机器学习有意思! 01》- 世界上最简单的机器学习入门

    本文首发于https jizhi im blog post ml is fun 01 你是否也曾听人们谈起机器学习但是只有一个朦胧的概念 你是否厌倦了在同事的高谈阔论中颓然欲睡 此诚求变之机 本教程适合所有对机器学习感到好奇 却不知从何下手
  • js的垃圾回收机制

    js 垃圾回收机制 GC 1 GC garbage collection js具有 自动 垃圾回收机制 即执行环境会负责管理代码执行过程中使用的内存 2 GC会定期 周期性的 找出那些不再继续使用的变量 然后释放其内存 3 不再使用的变量即
  • MySQL之explain 的type列 & Extra列

    explain 可以分析 select 语句的执行 即 MySQL 的 执行计划 一 type 列 MySQL 在表里找到所需行的方式 包括 由左至右 由最差到最好 All index range ref eq ref const syst