explain执行计划分析 ref_

news2024/11/27 16:34:36

这里写目录标题

  • 什么是Explain
  • Explain命令扩展
      • explain extended
      • explain partitions
  • 两点重要提示
  • 本文示例使用的数据库表
  • Explain命令(关键字)
      • explain简单示例
      • explain结果列说明
        • 【id列】
        • 【select_type列】
        • 【table列】
        • 【type列】
      • 【possible_keys列】
      • 【key列】
      • 【key_len列】
      • 【ref列】
      • 【rows列】
      • 【Extra列】
  • 查询优化建议
  • 索引使用情况分析
      • 数据库表
  • 实例说明
      • 实例一:
      • 实例二:
      • 实例三:
  • 总结

什么是Explain

Explain被称为执行计划,在语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,模拟MySQL优化器来执行SQL语句,执行查询时,会返回执行计划的信息,并不执行这条SQL。(注意,如果 from 中包含子查询,仍会执行该子查询,将结果放入临时表中)。

Explain可以用来分析SQL语句和表结构的性能瓶颈。通过explain的结果,可以了解到如数据表的查询顺序、数据查询操作的操作类型、哪些索引可以被命中、哪些索引实际会命中、每个数据表有多少行记录被查询等信息。

Explain命令扩展

explain extended

在explain的基础上提供一些额外的查询信息,在explian extended执行以后,通过show warnings命令可以得到优化后的查询语句,可以看出优化器做了哪些工作,还可以通过某些数据估算表连接的行数。

explain partitions

用于分析使用了分区的表,会显示出可能用到的分区。

两点重要提示

  1. Explain结果是基于数据表中现有数据的。
  2. Explain结果与MySQL版本有很大的关系,不同版本的优化器的优化策略不同。

本文示例使用的数据库表

在这里插入图片描述

Explain命令(关键字)

explain简单示例

mysql>explain select * from t_user;

在这里插入图片描述

在查询中的每个”表”会输出一行,这里的“表”的意义非常广泛,不仅仅是数据库表,还可以是子查询、一个union 结果等。

explain结果列说明

【id列】

id列是一个有顺序的编号,是查询的顺序号,有几个 select 就显示几行。id的顺序是按 select 出现的顺序增长的。id列的值越大执行优先级越高越先执行,id列的值相同则从上往下执行,id列的值为NULL最后执行。

【select_type列】

select_type列的值标明查询的类型:

1)simple:表明当前行对应的select是简单查询,不包含子查询和union

2)primary:表明当前行对应的select是复杂查询中最外层的 select

3)subquery:表明当前行对应的select是包含在 select 中的子查询(不在 from 子句中)

4)derived:表明当前行对应的select是包含在 from 子句中的子查询。

MySQL会创建一个临时表来存放子查询的查询结果。用如下的语句示例说明:

explain select (select 1 fromt_user where user_id=1) from (select * from t_group where group_id=1) tmp;

在这里插入图片描述

*注意,在资料收集过程中,发现不同版本的MySQL表现不一致,经反复对比,5.7及以后版本的输出如下:
在这里插入图片描述

很显然,MySQL在这方面进行了优化.

*注意,MySQL不同版本Explain表现差异很大,有些场景,从语句层面看,是要使用到索引,但经过优化器分析,结合表中现有数据,如果MySQL认为全表扫描性能更优,则会使用全表扫描。

5)union:表明当前行对应的select是在 union 中的第二个和随后的 select

6)union result:表明当前行对应的select是从 union 临时表检索结果的 select

explain select 1 union all select 2 fromdual;

在这里插入图片描述

MySQL5.7及以后同样做了优化

在这里插入图片描述

【table列】

table列的结果表明当前行对应的select正在访问哪个表。当查询的子句中有子查询时,table列是 格式,表示当前的select依赖 id=N结果行对应的查询,要先执行 id序号=N 的查询。当存在 union 时,UNION RESULT 的 table 列的值为<unionN1,N2>,N1和N2表示参与 union 的select 行的id序号。

【type列】

type列的结果表明当前行对应的select的关联类型或访问类型,也就是优化器决定怎么查找数据表中的行,以及查找数据行记录的大概范围。该列的取值优化程度的优劣,从最优到最差依次为:null>system> const > eq_ref > ref > range > index > ALL。一般来说,要保证查询达到range级别,最好达到ref。

1)null,MySQL优化器在优化阶段分解查询语句,在优化过程中就已经可以得到结果,那么在执行阶段就不用再访问表或索引。

explain select min(user_id) from t_user;

在这里插入图片描述

这时的函数min,在索引列user_id中选取最小值,可以直接查找索引来完成,不需要执行时再访问数据表。

2)const和system:const出现在用 primary key(主键) 或 unique key(唯一键) 的所有列与常数比较时,优化器对查询进行优化并将其部分查询转化成一个常量。最多有一个匹配行,读取1次,速度非常快。而system是const的特例,表中数据只有一条匹配时为system。此时可以用explain extended+show warnings查看执行结果。

explain extended select * from (select * from t_user where user_id = 1) tmp;

show warnings;

MySQL5.7:

7fbbcad2e902adebc13376fcfd9abeae.png
31f8f406a85311adb6a9b6b0727879d2.png

3)eq_ref:primary key(主键)或 unique key(唯一键) 索引的所有构成部分被join使用 ,只会返回一条符合条件的数据行。这是仅次于const的连接类型。

explain select * from t_group_user gu left join t_group g ong.group_id = gu.group_id;

在这里插入图片描述

  1. ref:与eq_ref相比,ref类型不是使用primary key(主键) 或 unique key(唯一键)等唯一索引,而是使用普通索引或者联合唯一性索引的部分前缀,索引和某个值相比较,可能会找到符合条件的多个数据行。
  1. 如下示例,使用的group_name是普通索引
explain select * from t_group where group_name= 'group1';

在这里插入图片描述

2.关联表查询

explain select g.group_id from t_group gleft join t_group_user gu on gu.group_id = g.group_id;

在这里插入图片描述

5)range:出现在 in(),between ,> ,<, >= 等操作符中。使用一个索引来查询给定范围的行。

6)index:扫描全表索引(index是从索引中读取的,所有字段都有索引,而all是从硬盘中读取),比ALL要快。

explain select * from t_group;

在这里插入图片描述

7)all:即全表扫描,需要从头到尾去查找所需要的行。一般这种情况下这需要增加索引来进行查询优化了

explain select * from t_user;

在这里插入图片描述

【possible_keys列】

这一列的结果表明查询可能使用到哪些索引。但有些时候也会出现出现possible_keys 列有结果,而 后面的key列显示 null 的情况,这是因为此时表中数据不多,优化器认为查询索引对查询帮助不大,所以没有走索引查询而是进行了全表扫描。

如果possible_keys列的结果是null,则表明没有相关的索引。这时,可以通过优化where子句,增加恰当的索引来提升查询性能。

【key列】

这一列表明优化器实际采用哪个索引来优化对该表的访问。如果没有使用索引,则该列是 null。

【key_len列】

这一列表明了在索引里使用的字节数,通过这个值可以大致估算出具体使用了联合索引中的前几个列。

key_len计算规则这里不再赘述,不同的数据类型所占的字节数是不一致的。

【ref列】

这一列表明了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名,如user.user_id

【rows列】

这一列表明优化器大概要读取并检测的行数。跟实际的数据行数大部分情况是不一致的。

【Extra列】

顾名思义,这一列表明的是额外信息,这一列的取值对优化SQL非常有参考意义。常见的重要取值如下:

1)using index:所有被查询的字段都是索引列(称为覆盖索引),并且where条件是索引的前导列,出现这样的结果,是性能高的表现。

explain select group_id,group_name from t_group;

在这里插入图片描述

2)using where:被查询的列未被索引覆盖,where条件也并非索引的前导列,表示 MySQL 执行器从存储引擎接收到查询数据,再进行“后过滤”(Post-filter)。所谓“后过滤”,就是先读取整行数据,再检查此行是否符合 where 句的条件,符合就留下,不符合便丢弃。

explain select * from t_user whereuser_name='user1';

在这里插入图片描述

3)using where Using index:被查询的列被索引覆盖,并且where条件是索引列之一但是不是索引的前导列,也就是没有办法直接通过索引来查询到符合条件的数据

explain select * from t_group where group_name = 'group1';

在这里插入图片描述

4)null:被查询的列没有被索引覆盖,但where条件是索引的前导列,此时用到了索引,但是部分列未被索引覆盖,必须通过“回表查询”来实现,不是纯粹地用到了索引,也不是完全没用到索引

explain select * from t_user where user_id='1';

在这里插入图片描述

5)using index condition:与using where类似,查询的列不完全被索引覆盖,where条件中是一个前导列的范围;这种情况未能通过示例显现,可能跟MySQL版本有关系。

6) using temporary:这表明需要通过创建临时表来处理查询。出现这种情况一般是要进行优化的,用索引来优化。创建临时表的情况:distinct,group by,orderby,子查询等

explain select distinct user_name from t_user;

在这里插入图片描述

explain select distinct group_name fromt_group; --group_name是索引列

在这里插入图片描述

  1. usingfilesort:在使用order by的情况下出现,mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。此时mysql会根据连接类型浏览所有符合条件的记录,并保存排序关键字和行指针,然后排序关键字并按顺序检索行信息。这种情况下要考虑使用索引来优化的。
explain select * from t_user orderby user_name;

在这里插入图片描述

explain select * from t_group order bygroup_name; --group_name是索引列

在这里插入图片描述

查询优化建议

结合前面的描述,首先看 type列的结果,如果有类型是 all 时,表示预计会进行全表扫描(fulltable scan)。通常全表扫描的代价是比较大的,建议创建适当的索引,通过索引检索避免全表扫描。

再来看下 Extra 列的结果,如果有出现 Using temporary 或者 Using filesort 则要多加关注:

  • Using temporary,表示需要创建临时表以满足需求,通常是因为GROUP BY的列没有索引,或者GROUP BY和ORDER BY的列不一样,也需要创建临时表,建议添加适当的索引。

  • Using filesort,表示无法利用索引完成排序,也有可能是因为多表连接时,排序字段不是驱动表中的字段,因此也没办法利用索引完成排序,建议添加适当的索引。

  • Using where,通常是因为全表扫描或全索引扫描时(type 列显示为 ALL 或index),又加上了WHERE条件,建议添加适当的索引。

索引使用情况分析

数据库表

主键索引:demo_id

联合索引:c1,c2,c3

在这里插入图片描述

实例说明

实例一:

explain select * from t_demo where c1='d1'and c2='d2' and c3='d3';

explain select * from t_demo where c2='d2'and c1='d1' and c3='d3';

explain select * from t_demo where c3='d3'and c1='d1' and c2='d3';

在这里插入图片描述

几个Sql表现一致

type=ref,ref=const,const,const

执行常量等值查询时,改变索引列的顺序并不会更改explain的执行结果,优化器会进行优化,推荐按照索引顺序列编写sql语句。

实例二:

explain select * from t_demo where c1='d1’and c2>‘d2’ and c3=‘d3’;

ce59d28ae7e48e1bf87097eca05b0764.png

explain select * from t_demo where c1='d1’and c3>‘d3’ and c2=‘d2’;
在这里插入图片描述

第一个例子范围右侧索引失效,使用到了两个索引。

第二个例子,由于优化器优化的原因,使用到了全部的三个索引。

实例三:

explain select * from t_demo wherec1>‘c’ and c2=‘d2’ and c3=‘d3’;

00b6e7ab3049a2022b7e5f8f83e43b10.png

explain select * from t_demo wherec1>‘e’ and c2=‘d2’ and c3=‘d3’;

32c9260dbd5fba441302d674b00c1947.png

从上面两个实例可以发现,同样使用最左的索引列范围查询,有些情况未用到索引,做了全表扫描(第一个例子);有些情况使用到了索引(第二个例子)。

经反复验证,发现如下规律(不一定可靠),也可能与数据的第一行或最小值相关。

  1. 跟存储的数据有关

  2. 在大于条件下,如果条件数据小于列数据,则索引无效;如果条件数据大于列数据,则索引有效;

在设计查询条件时,请注意规避。

针对第一个例子,可以采用覆盖索引的方式优化。

实例四:

explain select * from t_demo where c1='d1'and c2='d2' order by c3;

在这里插入图片描述

explain select * from t_demo where c1='d1'order by c3;

在这里插入图片描述

explain select * from t_demo where c1='d1’and c3=‘d3’ order by c2;

ea8785842b0b5670378650729464e2c4.png

order by排序使用到索引和没使用到索引的情况

实例五:

explain select * from t_demo where c1='d1'and c4='d4' order by c1,c2;

de647a4ef983af82bea443eacf6e2b3c.png

条件列包含没有索引的列,出现了Using filesort

实例六:
explain select * from t_demo where c1='d1’and c4=‘d4’ group by c1,c2;

77169502065010a4667d04c82982b83d.png

性能非常差的场景,同时出现了Using temporary和Using filesort

总结

  1. 两种方式的排序filesort和index,Usingindex是指MySQL扫描索引本身完成排序。index效率高,filesort效率低。

  2. order by满足两种情况会使用Using index。

    1)order by语句使用索引最左前列。

    2)使用where子句与order by子句条件列组合满足索引最左前列。

  3. 尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最佳左前缀法则。

  4. group by与order by很类似,都是先排序后分组,遵照索引创建顺序的最佳左前缀法则。

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

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

相关文章

1.2 图像处理基本操作

在本实战中&#xff0c;我们将学习如何使用OpenCV进行基本的图像处理操作。首先&#xff0c;我们将通过cv2.imread()函数读取图像&#xff0c;并使用cv2.imshow()在窗口中显示它。接着&#xff0c;我们将探索如何通过cv2.imwrite()保存图像&#xff0c;并设置不同的参数以控制图…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第十八集:制作UI系统的主菜单界面和选择存档界面

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作UI系统的主菜单界面 1.选择存档界面制作 2.代码的逻辑处理二、制作UI系统的选择存档界面 1.选择存档界面制作2.代码的逻辑处理总结 前言 hello大家好久…

Unity照片墙效果

Unity照片墙效果&#xff0c;如下效果展示 。 工程源码

华为HarmonyOS打造开放、合规的广告生态 - 贴片广告

场景介绍 贴片广告是一种在视频播放前、视频播放中或视频播放结束后插入的视频或图片广告。 接口说明 接口名 描述 loadAd(adParam: AdRequestParams, adOptions: AdOptions, listener: AdLoadListener): void 请求单广告位广告&#xff0c;通过AdRequestParams、AdOptions…

基于 Transformer 的语言模型

基于 Transformer 的语言模型 Transformer 是一类基于注意力机制&#xff08;Attention&#xff09;的模块化构建的神经网络结构。给定一个序列&#xff0c;Transformer 将一定数量的历史状态和当前状态同时输入&#xff0c;然后进行加权相加。对历史状态和当前状态进行“通盘…

【天线&运输】冲浪者检测系统源码&数据集全套:改进yolo11-DySnakeConv

改进yolo11-SCConv等200全套创新点大全&#xff1a;冲浪者检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.11.03 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”展示的系统图片或者视频可…

计算机毕业设计Hadoop+Spark大模型微博情感分析 微博舆情分析 微博爬虫 微博可视化 微博大数据分析 微博大数据 大数据毕业设计 Hive数据仓库

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

WPF中如何简单的使用MvvmLight创建一个项目并进行 增删改查

第一步&#xff1a;创建项目后下载如下两个NuGet程序包&#xff0c;然后删除删掉using Microsoft.Practices.ServiceLocation; 并且引入using CommonServiceLocator; 第二步&#xff1a;删除原来的XAML文件并创建如下的包结构然后创建一个在View文件夹中创建一个Main窗体 再将…

java项目之校园资料分享平台(springboot)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的校园资料分享平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 校园资料分享平台的主要…

Spring Security-02-Spring Security认证方式-HTTP基本认证、Form表单认证、HTTP摘要认证、前后端分离安全处理方案

Lison <dreamlison163.com>, v1.0.0, 2024.06.01 Spring Security-02-Spring Security认证方式-HTTP基本认证、Form表单认证、HTTP摘要认证、前后端分离安全处理方案 文章目录 Spring Security-02-Spring Security认证方式-HTTP基本认证、Form表单认证、HTTP摘要认证、…

2-9 存储管理

9.1 传统磁盘管理 1.添加磁盘 在关闭虚拟机情况下添加磁盘(SATA) 别忘记点确定&#xff01;&#xff01;&#xff01; 重启虚拟机&#xff0c;并查看磁盘情况 [rootlocalhost ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 20G…

word及Excel常见功能使用

最近一直在整理需规文档及表格&#xff0c;Word及Excel需要熟练使用。 Word文档 清除复制过来的样式 当复制文字时&#xff0c;一般会带着字体样式&#xff0c;此时可选中该文字 并使用 ctrlshiftN 快捷键进行清除。 批注 插入->批注&#xff0c;选中文本 点击“批注”…

【Linux 27】HTTP 协议中的 cookie 和 session

文章目录 &#x1f308;一、Cookie 的相关概念⭐ 1. Cookie 的概念⭐ 2. Cookie 的工作原理⭐ 3. Cookie 的分类⭐ 4. Cookie 的用途⭐ 5. Cookie 设置的基本格式⭐ 6. Cookie 设置时的注意事项⭐ 7. Cookie 的生命周期⭐ 8. Cookie 的安全性问题 &#x1f308; 二、Session 的…

SQL用一个字段查询出数据的交集

出个SQL查询的题吧&#xff0c;有兴趣的可以看看 1、问题 下面有一份数据&#xff08;图1&#xff09;&#xff0c;由两部分组成&#xff1a;分析数据和基准数据 分析数据标识列为1&#xff0c;基准数据标识列为1&#xff0c;两字段0,1互斥 要求&#xff1a;按找出两部分数据…

后端java——如何为你的网页设置一个验证码

目录 1、工具的准备 2.基本方法 3.实现类 4.实践 HTML文件&#xff1a; Java文件1:创建验证码 Java文件2:验证验证码 本文通过HUTOOL实现&#xff1a;Hutool参考文档Hutool&#xff0c;Java工具集https://hutool.cn/docs/#/ 1、工具的准备 如果我们通过hutool来实现这个…

【Python单元测试】pytest框架单元测试 配置 命令行操作 测试报告 覆盖率

单元测试&#xff08;unit test&#xff09;&#xff0c;简称UT。本文将介绍在Python项目中&#xff0c;pytest测试框架的安装&#xff0c;配置&#xff0c;执行&#xff0c;测试报告与覆盖率 pytest简介 pytest是一款流行的&#xff0c;简单易上手的单元测试框架&#xff0c;…

HTMLCSS:呈现的3D树之美

效果演示 这段代码通过HTML和CSS创建了一个具有3D效果的树的图形&#xff0c;包括分支、树干和阴影&#xff0c;通过自定义属性和复杂的变换实现了较为逼真的立体效果。 HTML <div class"container"><div class"tree"><div class"…

练习LabVIEW第三十八题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十八题&#xff1a; 创建一个VI&#xff0c;实现对按钮状态的指示和按钮“按下”持续时间简单计算功能&#xff0c;按…

HomeAssistant自定义组件学习-【二】

#要说的话# 前面把中盛科技的控制器组件写完了。稍稍熟悉了一些HA&#xff0c;现在准备写窗帘控制组件&#xff0c;构想的东西会比较多&#xff0c;估计有些难度&#xff0c;过程会比较长&#xff0c;边写边记录吧&#xff01; #设备和场景环境# 使用的是Novo的电机&#xf…

Linux脚本数组与字符串

文章目录 打印数组与长度数组遍历数组赋值下标索引访问切片追加()删除关联数组(像map)字符串字符拼接截取子串字符串长度字符串替换模式匹配截取分割字符串大小写转换 打印数组与长度 ${arrayName[*]} 打印数组${arrayName[]} 打印数组${#arrayName[*]} 打印数组长度${#arrayN…