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

news2024/12/30 1:03:38

在这里插入图片描述​🌈 个人主页: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值就是PRIMARY

    SUBQUERY:包含在 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 > ALL
    SQL性能优化的目标:至少要达到range级别,要求是ref级别,最好是consts级别。
    system:当表中只有一条记录并且该表使用的存储引擎的统计数据都是精确地,表最多有一个匹配行,读取1次,速度比较快。
    const:system是 const的特例,表里只有一条元组匹配时为system
    eq_ref:primary key 或 unique key 索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录。
    ref:相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会 找到多个符合条件的行。
    range:用索引获取某些范围区间的记录。

 


select_type

 

    每个select对应一个select_type,表示select的复杂度
    SIMPLE:简单查询。查询不包含子查询和union,如上图
    PRIMARY:对于包含UNION、UNION ALL或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的select_type值就是PRIMARY
    SUBQUERY:包含在 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 = 17
       explain中key_len值为17
    

 

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

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

 
数值类型:
 

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

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

 

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

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

 

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

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

 

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

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

 
时间类型:
 

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

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

 

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

       col8_timestamp是timestamp,那么len应该是 4+可为空1 = 5
       explain中key_len值为5
       datetime:无小数秒位数,占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 = 6
       explain中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.coloradmin.cn/o/1807048.html

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

相关文章

Linux|如何安装 Java

引言 Java是最受欢迎的编程语言之一&#xff0c;JVM&#xff08;Java的虚拟机&#xff09;是运行Java应用程序的运行时环境。这两个平台是许多流行软件所需的&#xff0c;包括Tomcat&#xff0c;Jetty&#xff0c;Cassandra&#xff0c;Glassfish和Jenkins。 本教程[1]将指导您…

关闭Cloudflare Pages的访问策略

curl API 获取相应的 uid curl -X GET "https://api.cloudflare.com/client/v4/accounts/账户标识符/access/apps" \-H "X-Auth-Email: 邮箱" \-H "X-Auth-Key: Global API KEY" \-H "Content-Type: application/json"账户标识符是登…

C# WPF入门学习主线篇(十九)—— 布局管理实战『混合布局案例』

C# WPF入门学习主线篇&#xff08;十九&#xff09;—— 布局管理实战『混合布局案例』 欢迎来到C# WPF入门学习系列的第十九篇。在前几篇文章中&#xff0c;我们详细介绍了各个布局容器的基本概念和使用方法。本篇博客将通过一个综合的实战案例&#xff0c;展示如何在WPF中使用…

Python第二语言(五、Python文件相关操作)

目录 1. 文件编码的概念 2. 文件的读取操作 2.1 什么是文件 2.2 open()打开函数 2.3 mode常用的三种基础访问模式 2.4 文件操作及案例 3. 文件的写入操作及刷新文件&#xff1a;write与flush 4. 文件的追加操作 5. 文件操作的综合案例&#xff08;文件备份操作&#x…

【SQLAlChemy】常见的数据类型有哪些,Column可选的参数有哪些呢?

常见数据类型与Column参数 常见类型 Integer&#xff1a;整数类型&#xff0c;对应数据库的 int 类型。Float&#xff1a;浮点数类型&#xff0c;对应数据库的 float 类型。它占用 32 位空间。Double&#xff1a;双精度浮点数类型&#xff0c;对应数据库的 double 类型&#…

AI演进之道:剖析大模型技术的四大核心架构

▼最近直播超级多&#xff0c;预约保你有收获 随着 AI 大模型技术的持续进步&#xff0c;大模型的技术框架经历了不断优化与革新。本文我们将细致解析四种关键的大模型技术结构&#xff1a;纯粹 Pompt 提示词法、Agent Function Calling 机制、RAG&#xff08;检索增强生成&am…

Java物业管理系统+数据库应用程序开发[JavaSE+JDBC+idea控制台+MySQL]

背景&#xff1a; 使用JavaSEJDBCMySQL技术实现一个物业管理系统&#xff0c;具体要求如下 物业管理系统需求&#xff1a; 需求分析 1.1用户需求分析 在进入系统之前&#xff0c;要进行身份确认&#xff0c;只有用户名和用户密码都相符的用户方可进入本系统&#xff0c;为…

基于Java的超市进销存管理系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; Java JSP Servlet JavaBean 工具&#xff1a; IDEA/Eclipse、…

TS 小技巧: 使用元组生成联合类型

前言 在我们使用 TypeScript 开发业务的时候&#xff0c;也许你会遇到一个这样的问题&#xff1a;我们如何根据一个数组的值得到一个联合类型&#xff1f; 这里向大家介绍一个开发小技巧&#xff1a;使用元组生成联合类型 开发场景 我们看下面一段 ts 代码&#xff1a; con…

Java Web学习笔记31——Maven介绍

Maven&#xff1a;Java项目的构建工具。 Maven&#xff1a; Maven是Apache旗下的一个开源项目&#xff0c;是一款用于管理和构建Java项目的工具。 Apache软件基金会&#xff0c;成立于1999年7月&#xff0c;是目前世界上最大的最受欢迎的开源软件基金会&#xff0c;也是一个专…

【30天精通Prometheus:一站式监控实战指南】第18天:apache_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们&#x1f44b;   欢迎加入【30天精通Prometheus】专栏&#xff01;&#x1f4da; 在这里&#xff0c;我们将探索Prometheus的强大功能&#xff0c;并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。&#x1f680;   Prometheus是云原生和DevOps的…

OpenCV绘制直线

一 绘制图形 画线 画矩形 画圆 画椭圆 画多边形 绘制字体 二 画线 line(img,开始点&#xff0c;结束点&#xff0c;颜色…) 参数结束 img&#xff1a;在那个图像上画线 开始点,结束点&#xff1a;指定线的开始与结束位置&#xff1b; 颜色&#xff0c;线宽&#xff0c;线体…

在 SEO 中,一个好的网页必须具备哪些 HTML 标签和属性?

搜索引擎优化 &#xff08;SEO&#xff09; 是涉及提高网站在搜索引擎上的可见性的过程。这是通过提高网站在搜索引擎结果页面&#xff08;例如Google&#xff09;上的排名来实现的。网站在这些页面上的显示位置越高&#xff0c;就越有可能获得更大的流量。 搜索引擎优化涉及了…

Duilib多标签选项卡拖拽效果:添加动画特效!

动画是小型界面库的“难题”、“通病” 几年前就有人分享了如何用direct UI制作多标签选项卡界面的方法。还有人出了一个简易的浏览器demo。但是他们的标签栏都没有Chrome浏览器那样的动画特效。 如何给界面添加布局是的动画特效呢&#xff1f; 动画使界面看起来高大上&#…

AbstractMap和SimpleEntry

一、AbstractMap 位置&#xff1a;在java.util包 二、SimpleEntry 1、概述 继承了Map中的内部接口Entry<K,V> SimpleEntry<K,V>不仅继承了Map.Entry<K,V>&#xff0c;还继承了序列化的接口 2、构造方法 方法说明SimpleEntry(K key,V value)通过键值对初…

美团大规模KV存储挑战与架构实践--图文分析

美团大规模KV存储挑战与架构实践–图文分析 原作者&#xff1a;美团技术团队 原文链接&#xff1a;https://tech.meituan.com/2024/03/15/kv-squirrel-cellar.html 1 美团 KV 存储发展历程 第一代&#xff1a;使用Memcached 什么是一致性哈希&#xff1f; 哈希&#xff1a…

[Mdfs] lc3067. 在带权树网络中统计可连接服务器对数目(邻接表+图操作基础+技巧+好题)

文章目录 1. 题目来源2. 题目解析 1. 题目来源 链接&#xff1a;3067. 在带权树网络中统计可连接服务器对数目 2. 题目解析 挺有意思的一道题目&#xff0c;重点是要能够读懂题目&#xff0c;然后结合几个图相关的处理技巧即可拿下。 图存储&#xff1a;邻接表即可。无向无…

【Redis】什么是Redis缓存 雪崩、穿透、击穿?(一篇文章就够了)

目录 什么是Redis? Redis的正常存储流程&#xff1f; 什么是Redis缓存雪崩&#xff1f; 缓存雪崩 缓存预热 缓存失效时间的随机性 什么是Redis缓存穿透&#xff1f; 缓存穿透 缓存空对象 BloomFilter&#xff08;布隆过滤器&#xff09; 什么是Redis缓存击穿&#…

LabVIEW 用于 MES 系统和卡钳上位机检测

LabVIEW 确实可以用于制造执行系统&#xff08;MES&#xff09;的开发以及卡钳上位机检测。以下是详细说明&#xff1a; 使用 LabVIEW 开发 MES 系统 数据采集与处理&#xff1a;LabVIEW 擅长实时数据采集和处理&#xff0c;可以连接多种传感器和设备&#xff0c;获取生产线上…