轻松上手MYSQL:SQL优化之Explain详解

在这里插入图片描述​🌈 个人主页:danci_
🔥 系列专栏:《设计模式》《MYSQL应用》
💪🏻 制定明确可量化的目标,坚持默默的做事。


文章目录

  • 一、Explain
    • 1.1 explain作用
    • 1.2 explain列说明
      • `id`
      • `select_type`
      • `table`
      • `partiitons`
      • `type`
      • `select_type`
      • `possible_keys`
      • `key`
      • `key_len(key_len值计算)`
      • `key_len的计算:(举几个类型)`
      • `ref`
      • `rows`
      • `filtered`
      • `Extra`

一、Explain

1.1 explain作用

    在sql语句前添加explain,作用是查看mysql对这条sql的执行计划信息。思考:MYSQL执行SQL语句时一定按这个执行计划执行么?

 

1.2 explain列说明

 
    在一条简单SQL前面添加explain查看有哪些列,如下:
 
在这里插入图片描述
 


id

 
每个select对应一个id值,其值是按 select 出现的顺序增长的。
注:id值越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行
 


select_type

 
每个select对应一个select_type,表示select的复杂度,有:
SIMPLE:简单查询。查询不包含子查询和union,如上图

    PRIMARY:对于包含UNION、UNION ALL或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的select_type值就是PRIMARYSUBQUERY:包含在 select 中的子查询(不在 from 子句中)DERIVED:对于包含‘派生表’的查询UNION:在 union 中的第二个和随后的 select

 


table

 

    这一列表示 explain 的一行正在访问哪个表。当 from 子句中有子查询时,table列是 <derivenN> 格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N 的查 询。当有 union 时,UNION RESULT 的 table 列的值为<union1,2>,1和2表示参与 union 的 select 行id。

 


partiitons

 

    匹配的分区信息

 


type

 

    这一列表示关联类型或访问类型效率从最优到最差分别为:system > const > eq_ref > ref > range > index > ALLSQL性能优化的目标:至少要达到range级别,要求是ref级别,最好是consts级别。system:当表中只有一条记录并且该表使用的存储引擎的统计数据都是精确地,表最多有一个匹配行,读取1次,速度比较快。const:system是 const的特例,表里只有一条元组匹配时为systemeq_ref:primary key 或 unique key 索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录。ref:相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会 找到多个符合条件的行。range:用索引获取某些范围区间的记录。

 


select_type

 

    每个select对应一个select_type,表示select的复杂度SIMPLE:简单查询。查询不包含子查询和union,如上图PRIMARY:对于包含UNION、UNION ALL或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的select_type值就是PRIMARYSUBQUERY:包含在 select 中的子查询(不在 from 子句中)DERIVED:对于包含‘派生表’的查询UNION:在 union 中的第二个和随后的 select

 


possible_keys

 

    标识某个表查询时可能使用哪些索引来查找。        

 


key

 

    实际使用哪个索引。当possible_keys有值,而key没有值时,可能是因为表数据很少,mysql认为没有必要走索引,直接全表查询了。当possible_keys为null时,可根据实际情况在where条件中添加索引来提升查询效率。

 


key_len(key_len值计算)

 

     实际使用到的索引的字节数,帮我们检查是否充分利用上了索引,对于联合索引有一定的参考意义。

    比如有列n和address的联合索引(表my_datas字段有id, n, address 和 time)
 
在这里插入图片描述
 
在这里插入图片描述
 

     key_len=5,通过计算索引占的字节数来判断出查询使用了联合索引中的第一个列。

 


key_len的计算:(举几个类型)

 
    测试表test1
 
在这里插入图片描述
 
 
 
字符串:char(n)和varchar(n),5.0.3以后版本中,n均代表字符数,而不是字节数,如果是utf-8,一个数字或字母占1个字节,一个汉字占3个字节

 

  • char(n):如果存汉字长度就是 4n 字节(若可为空 则+1)
     
    在这里插入图片描述
     

       col1_char是char(4),那么len应该是 4*4 + 可为空1 = 17explain中key_len值为17
    

 

  • varchar(n):如果存汉字则长度是 4n + 2 字节(若可为空 则+1),加的2字节用来存储字符串长度,因为 varchar是变长字符串。
     
    在这里插入图片描述
     

       col2_varchar是varchar(32),那么len应该是 32 * 4 + 2 + 1 = 131explain中key_len值为131
    

 
数值类型:
 

  • tinyint:1字节(若可为空 则+1)
     
    在这里插入图片描述
     

       col3_tinyint是tinyint,那么len应该是 1+可为空1 = 2explain中key_len值为2   
    

 

  • smallint:2字节(若可为空 则+1)
     
    在这里插入图片描述
     

       col4_smallint是smallint,那么len应该是 2+可为空1 = 3explain中key_len值为3
    

 

  • int:4字节(若可为空 则+1)
     
    在这里插入图片描述
     

       col5_int是int,那么len应该是 4+可为空1 = 5explain中key_len值为5
    

 

  • bigint:8字节 (若可为空 则+1)
     
    在这里插入图片描述
     

       col6_bigint是bigint,那么len应该是 8+可为空1 = 9explain中key_len值为9
    

 
时间类型:
 

  • date:3字节(若可为空 则+1)
     
    在这里插入图片描述
     

       col7_date是date,那么len应该是 3 + 可为空1 = 4explain中key_len值为4
    

 

  • timestamp:4字节(若可为空 则+1)
     
    在这里插入图片描述
     

       col8_timestamp是timestamp,那么len应该是 4+可为空1 = 5explain中key_len值为5datetime:无小数秒位数,占5个字节。datetime(n) 其中n是保留的小数秒位数,额外占的存储空间分别为n=0时      额外空间0字节n=1(或2)  额外空间1字节n=3(或4)  额外空间2字节n=5(或6)  额外空间3字节col9_datetime是datetime,那么len应该是 5+可为空1 = 6explain中key_len值为6
    

    注:

     - myisam 表,单列索引,最大长度不能超过 1000 bytes,否则会报警,但是创建成功,最终创建的是前缀索引(取前333个字符);- myisam 表,组合索引,索引长度和不能超过 1000 bytes,否则会报错,创建失败;- innodb 表,单列索引,超过 767 bytes的,给出warning,最终索引创建成功,取前缀索引(取前 255 字符);- innodb 表,组合索引,各列长度不超过 767 bytes ,如果有超过 767 bytes 的,则给出报警,索引最后创建成功, 但是对于超过 767 字节的列取前缀索引,与索引列顺序无关,总和不得超过 3072 ,否则失败,无法创建;

 


ref

 

    这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量)、字段名(库名.表名.列名 如test.test.col1_char)

 


rows

 

    这一列是mysql估计要读取并检测的行数,值越小越优注意这个不是结果集里的行数                

 


filtered

 

    通过索引扫描表估计要读取并检测的行数rows。使用额外的查询条件对rows行的数据进行过滤行得有行数n占rows的比例,即 n/rows * 100%

 


Extra

 

    sql执行计划比较重要的参考信息,常见重要信息如下:

 

  • 1 Using index:使用索引覆盖
     
    索引覆盖:查询的字段信息从这条sql使用的索引(辅助索引)树中获取。如:
     
    在这里插入图片描述
     

      查询的字段是索引(col4_smallint)中的字段col4_smallint信息也就是说,不需要通过辅助索引找到主键,再通过主键树获取想要的信息
    

 

  • 2 Using where:使用where查询数据,需要回表去获取需要的数据
     
    在这里插入图片描述
     
     
  • 3 Using index condition:相当于索引覆盖后通过主键回表查询,再通过where过滤
     
    在这里插入图片描述
     
     
  • 4 Using temporary:创建一张临时表来处理查询
     
    在这里插入图片描述
     
     
  • 5 Using filesort:顾名思义,使用文件(磁盘中)排序。mysql做了优化,数据较少时排序是在内在中进行的,数据量较大时才会在磁盘中进行排序。出现这种情况,就要考虑添加索引来优化SQL了。
     
    在这里插入图片描述
     
        col1_char 未创建索引,mysql先预览整个表对col1_char进行排序和对应的主键值序列,再通过主键值回主键索引树查询数据返回。
        对 col1_char 添加索引之后,执行计划结果如下:
     
    在这里插入图片描述
     
     
  • 6 Select tables optimized away:使用函数来查询某个索引信息时
     
    在这里插入图片描述
     
     
        希望你喜欢这篇文章!不要忘记 "点赞" 和 "关注" 哦,我们下次见!🎈
     

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/25190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React antd 怎么封装权限按钮

在 React 中使用 Ant Design(antd)封装一个权限按钮通常涉及到两个主要部分:按钮的渲染逻辑和权限的验证。以下是一个基本的步骤和示例代码,展示如何封装一个权限按钮: 步骤 定义权限:首先,你需要定义应用中的权限。这些权限可能是一个简单的字符串数组,或者是更复杂的…

6.9总结(省赛排位赛1)

省赛排位赛1省赛排名赛1 - Virtual Judge (vjudge.net) 思路&#xff1a; 其实就是一个斐波拉契数列&#xff0c;当前项前两项之和&#xff0c;先将范围内的数全部存起来放进一个数组&#xff0c;再进行累加查询 代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #incl…

Nginx替代软件

Nginx 是一款广受欢迎的高性能 Web 服务器&#xff0c;以其事件驱动的架构和轻量级的特点而闻名。尽管 Nginx 非常强大&#xff0c;但确实存在一些替代品&#xff0c;它们各自具有独特的优点。以下是一些 Nginx 的替代软件及其优点&#xff1a; 1. LiteSpeed - LiteSpeed 是…

将单条十六进制字符串转换为单个 pcap 文件

第一步&#xff1a;将字符串转换为 hex 格式文件 echo 01005e00000ac20173fe0000080045c0003c000000000258cd9f0a000001e000000a0205ee68000000000000000000000000000000640001000c010001000000000f000400080c040102 | xxd -r -p | od -Ax -tx1 > icmp.pcap 第二步&#x…

《一心体系至善算法》“人文+AI”成果

《一心体系至善算法》“人文AI”成果 人工智能&#xff08;AI&#xff09;和通用人工智能&#xff08;AGI&#xff09;的伦理与安全问题: 在《中法联合声明》中&#xff0c;着重强调了AI向善问题。在探讨人工智能&#xff08;AI&#xff09;和通用人工智能&#xff08;AGI&…

Leetcode:三数之和

题目链接&#xff1a;15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 普通版本&#xff08;排序 双指针法&#xff09; 分析&#xff1a; 1、我们可以通过三个循环嵌套找到符合题目要求的三元组组合 2、但由于题目要求中的三元组i、j、k并不要求连续&#xff0c;所以会…

【Tools】 探索 Chrome DevTools:前端开发者的必备工具

我已经从你的 全世界路过 像一颗流星 划过命运 的天空 很多话忍住了 不能说出口 珍藏在 我的心中 只留下一些回忆 &#x1f3b5; 牛奶咖啡《从你的全世界路过》 在现代Web开发中&#xff0c;Chrome DevTools&#xff08;开发者工具&#xff09;是前端开发…

彩虹易支付最新版源码

源码简介 彩虹易支付最新版源码&#xff0c;更新时间为5.1号 2024/05/01&#xff1a; 1.更换全新的手机版支付页面风格 2.聚合收款码支持填写备注 3.后台支付统计新增利润、代付统计 4.删除结算记录支持直接退回商户金额 安装环境 1.PHP版本>7.4 2.Mysql数据库 安装教…

Leetcode:电话号码的字母组合

题目链接&#xff1a;17. 电话号码的字母组合 - 力扣&#xff08;LeetCode&#xff09; 普通版本&#xff08;回溯&#xff09; class Solution { public:string tmp;//临时存放尾插内容vector<string> res;//将尾插好的字符串成组尾插给resvector<string> board{…

【小沐学Python】Python实现Web服务器(CentOS下打包Flask)

文章目录 1、简介2、下载Python3、编译Python4、安装PyInstaller5、打包PyInstaller6、相关问题6.1 ImportError: urllib3 v2 only supports OpenSSL 1.1.1, currently the ssl module is compiled with OpenSSL 1.0.2k-fips 26 Jan 2017. See: https://github.com/urllib3/url…

Linux系统管理:虚拟机Almalinux 9.4 安装

目录 一、理论 1.Almalinux 二、实验 1.虚拟机Almalinux 9.4 安装准备阶段 2.安装Almalinux 9.4 3.Termius远程连接 一、理论 1.Almalinux (1) 简介 Almalinux是一个开源、社区拥有和管理、免费的企业Linux发行版。专注于长期稳定性&#xff0c;并提供强大的生产级…

1025 反转链表

solution 模拟链表&#xff1a;记录链表中第i个元素的地址&#xff0c;再记录每个给定地址的对应数据和下一结点地址。注意给出的结点可能有的无效 #include<iostream> #include<algorithm> using namespace std; const int maxn 1e5 10; int main(){int n, k,…

Nginx(title小图标)修改方法

本章主要讲述Nginx如何上传网站图标。 操作系统&#xff1a; CentOS Stream 9 首先我们bing搜索ico网站图标在线设计&#xff0c;找到喜欢的设计分格并下载。 是一个压缩包 然后我们上传到nginx解压 [rootlocalhost html]# rz[rootlocalhost html]# unzip favicon_logosc.z…

【AI大模型】Prompt Engineering

目录 什么是提示工程&#xff08;Prompt Engineering&#xff09; Prompt 调优 Prompt 的典型构成 「定义角色」为什么有效&#xff1f; 防止 Prompt 攻击 攻击方式 1&#xff1a;著名的「奶奶漏洞」 攻击方式 2&#xff1a;Prompt 注入 防范措施 1&#xff1a;Prompt 注…

请求 响应

在web的前后端分离开发过程中&#xff0c;前端发送请求给后端&#xff0c;后端接收请求&#xff0c;响应数据给前端 请求 前端发送数据进行请求 简单参数 原始方式 在原始的web程序中&#xff0c;获取请求参数&#xff0c;需要通过HttpServletRequest 对象手动获取。 代码…

Thinkphp5实现自定义路由和使用方法

在 ThinkPHP 5 中&#xff0c;实现自定义路由方法通常涉及到定义路由规则和对应的处理逻辑。虽然 ThinkPHP 5 的路由系统已经相当强大和灵活&#xff0c;但如果你需要实现自定义的路由方法&#xff0c;你可能需要扩展或修改现有的路由解析机制。 不过&#xff0c;对于大多数情…

SpringBoot——整合WebSocket长连接

目录 WebSocket 项目总结 新建一个SpringBoot项目 pom.xml WebSocketConfig配置类 TestWebSocketEndpoint服务端点类 socket.html客户端 IndexController控制器 SpringbootWebsocketApplication启动类 测试客户端和服务端如何使用WebSocket进行连接和通信 WebSocket S…

vscode 突然无法启动 WSL terminal 了怎么办?

参考&#xff1a;https://github.com/microsoft/vscode/issues/107485 根据参考网页&#xff0c;似乎在 windows 更新之后&#xff0c;重启&#xff0c;就有可能出现标题所说的 vscode 无法启动 WSL terminal 的情况。 首先使用 cmd 进入 wsl 终端&#xff0c;把 ~/.vscode-se…

(八)Mybatis持久化框架原理之不同Executor对比和Spring事务关系

文章目录 1. SqlSession的差异2. Executor的差异2.1 SimpleExecutor流程说明2.2 ReuseExecutor流程说明2.3 BatchExecutor流程说明 3. Mybatis事务4. Spring事务5. 总结 本篇文章主要是由一次批量插入数据而引起的思考与探究&#xff0c;在这篇文章中将会分析不同的Executor和S…

Vue3+springboot+sa-token

sa-token是什么? sa-token官网Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。 springboot前后端分离集成sa-token maven <!-- Sa-Token 权限认证,在线文档:…