一文带你了解MySQL的Explain

news2024/12/26 0:10:52

日常工作中,我们经常会收到慢sql告警,前面也写过两篇优化文章,SQL的优化思路和使用规范_出世&入世的博客-CSDN博客

MySQL优化策略_出世&入世的博客-CSDN博客 

在优化这些慢sql时,我们经常需要用到explain这个命令来查看一个这些慢SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描。

今天讲解一下explain 命令:

-- 实际SQL,查找用户名为Jefabc的员工
select * from emp where name = 'Jefabc';
-- 查看SQL是否使用索引,前面加上explain即可
explain select * from emp where name = 'Jefabc';

expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra

概要描述:

  1. id:选择标识符
  2. select_type:表示查询的类型。
  3. table:输出结果集的表
  4. partitions:匹配的分区
  5. type:表示表的连接类型
  6. possible_keys:表示查询时,可能使用的索引
  7. key:表示实际使用的索引
  8. key_len:索引字段的长度
  9. ref:列与索引的比较
  10. rows:扫描出的行数(估算的行数)
  11. filtered:按表条件过滤的行百分比
  12. Extra:执行情况的描述和说明

1、id

SELECT识别符。这是SELECT的查询序列号

我的理解是SQL执行的顺序的标识,SQL从大到小的执行

  1. id相同时,执行顺序由上至下

  2. 如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

  3. id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行

-- 查看在研发部并且名字以Jef开头的员工,经典查询
explain select e.no, e.name from emp e left join dept d on e.dept_no = d.no where e.name like 'Jef%' and d.name = '研发部';

 

2、select_type

示查询中每个select子句的类型

  1. SIMPLE(简单SELECT,不使用UNION或子查询等)
  2. PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
  3. UNION(UNION中的第二个或后面的SELECT语句)
  4. DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
  5. UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select)
  6. SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)
  7. DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询)
  8. DERIVED(派生表的SELECT, FROM子句的子查询)
  9. UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)

3、table

显示这一步所访问数据库中表名称(显示这一行的数据是关于哪张表的),有时不是真实的表名字,可能是简称,例如上面的e,d,也可能是第几步执行的结果的简称

4、type

对表访问方式,表示MySQL在表中找到所需行的方式,又称“访问类型”。

常用的类型有: ALL、index、range、 ref、eq_ref、const、system、****NULL(从左到右,性能从差到好

  • ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

  • index:Full Index Scan,index与ALL区别为index类型只遍历索引树

  • range:只检索给定范围的行,使用一个索引来选择行

  • ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

  • eq_ref:类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件

  • const、system:当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system

  • NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

5、possible_keys

指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用(该查询可以利用的索引,如果没有任何索引显示 null

该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

6、Key

key列显示MySQL实际决定使用的键(索引),必然包含在possible_keys中

如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

7、key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)

不损失精确性的情况下,长度越短越好

8、ref

列与索引的比较,表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

9、rows

估算出结果集行数,表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数

10、Extra

该列包含MySQL解决查询的详细信息,有以下几种情况:

create table test_order
(
    id int auto_increment primary key,
    user_id int,
    order_id int,
    order_status tinyint,
    create_date datetime
);

create table test_orderdetail
(
    id int auto_increment primary key,
    order_id int,
    product_name varchar(100),
    cnt int,
    create_date datetime
);

create index idx_userid_order_id_createdate on test_order(user_id,order_id,create_date);

create index idx_orderid_productname on test_orderdetail(order_id,product_name);

 

10.1、Using index

查询的列被索引覆盖,并且where筛选条件是索引的前导列并且where筛选条件与查询的列,属于一颗索引树!不需要回表

 

10.2、Using where

  • 查询的列未被索引覆盖,where筛选条件非索引的前导列

  • 查询的列未被索引覆盖,where筛选条件非索引列

 

  • 查询的列未被索引覆盖,where筛选条件索引前导列的范围查询

 

Using where表示**没有可用的索引查找**,要考虑索引扫描+回表表扫描`的代价。

10.3、Using index condition

意味着查询列的某一部分无法直接使用索引,需要回表

1.查询的列不完全被索引覆盖,where条件中是一个前导列的范围

 

  • 如果禁用ICP(set optimizer_switch=‘index_condition_pushdown=off’),  执行计划是using where,意味着全表扫描,

  • 如果启用ICP,执行计划为using index Condition,意味着在筛选的过程中实现过滤

如果查询的数据范围过大,执行计划是using where,意味着全表扫描,

2.查询列不完全被索引覆盖,查询条件完全可以使用到索引(进行索引查找)

查询条件无法直接使用索引,隐含了一个查找+筛选的过程。

10.4、Using where Using index

  • 查询的列被索引覆盖,并且where筛选条件是索引列之一但是不是索引的前导列-表示无法直接通过索引查找查询到符合条件的数据

  • 查询的列被索引覆盖,并且where筛选条件是索引列前导列的一个范围-同样表示无法直接通过索引查找查询到符合条件的数据

10.5、NULL(没有信息)

  • 查询的列未被索引覆盖,并且where筛选条件是索引的前导列 - 意味着查询用到了索引,但是部分字段未被索引覆盖,必须通过“回表”来实现

  • 查询的列被索引覆盖,且where筛选条件是索引的前导列,但是二者不是同一颗索引树

 

10.6、Using temporary

表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询,常见 group by ; order by

10.7、Using filesort

当Query中包含 order by 操作,而且无法利用索引完成的排序操作称为“文件排序”

-- 测试Extra的filesort
explain select * from emp order by name;

 

总结

1 Extra中的为Using index的情况
查询列被索引覆盖 && where筛选条件是一个基于索引前导列的查询,意味着 通过索引查找就能直接找到符合条件的数据,并且无须回表

2 Extra中的为空的情况
查询列未被索引覆盖 && where筛选列是索引的前导列,意味着通过索引查找并且通过回表来找到未被索引覆盖的字段,

3 Extra中的为Using where;
使用了索引: 要考虑索引扫描+回表
未使用索引:表扫描的代价。

4 Extra中的为Using where; Using index
查询列被索引覆盖 `&& 同3

注意:
• EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
• EXPLAIN不考虑各种Cache
• EXPLAIN不能显示MySQL在执行查询时所作的优化工作
• 部分统计信息是估算的,并非精确值
• EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划。

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

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

相关文章

aws dynamodb java低等级api和高级客户端api的使用

参考资料 https://docs.amazonaws.cn/zh_cn/sdk-for-java/latest/developer-guide/setup-project-maven.html 初始化环境 创建maven项目 mvn org.apache.maven.plugins:maven-archetype-plugin:3.1.2:generate \-DarchetypeArtifactId"maven-archetype-quickstart&quo…

正则表达式引擎NFA自动机的回溯解决方案总结

前几天线上一个项目监控信息突然报告异常,上到机器上后查看相关资源的使用情况,发现 CPU 利用率将近 100%。通过 Java 自带的线程 Dump 工具,我们导出了出问题的堆栈信息。 我们可以看到所有的堆栈都指向了一个名为 validateUrl 的方法&#…

【C语言】每日刷题 —— 牛客语法篇(4)

🚀🚀前言 大家好,继续更新专栏 c_牛客,不出意外的话每天更新十道题,难度也是从易到难,自己复习的同时也希望能帮助到大家,题目答案会根据我所学到的知识提供最优解。 🏡个人主页&am…

Mr. Cappuccino的第48杯咖啡——冒泡APP(升级版)之基于Docker部署企业级Maven私服

冒泡APP(升级版)之基于Docker部署企业级Maven私服基于Docker安装Nexus登录Maven私服配置Maven仓库配置settings.xml和pom.xml项目实践及常见问题基于Docker安装Nexus 查看sonatype/nexus镜像版本 下载指定版本的镜像 docker pull sonatype/nexus3:3.48…

【C语言】有关的经典题型内含数组及递归函数题型讲解(入门适用)

C语音经典题型1. 在屏幕上输出9*9乘法口诀表2. 求10 个整数中最大值3. 计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值,打印出结果4. 编写程序数一下 1到 100 的所有整数中出现多少个数字95. 能把函数处理结果的二个数据返回给主调函数6. 实现一个函数,…

Https 笔记

HTTP TLS TLS 的前身是 SSL 非对称加密的核心: 两个密钥(公私) https 需要第三方CA(证书授权中心)申请SSL证书以确定其真实性 证书种包含了特定的公钥和私钥 密钥交换 自己将私钥上锁后发给对方对方也上锁 在还回来…

【2023包河区】题解

今天早上也是打完了包河区,不得不说是太 了 所以说,还是水一篇文章吧 T1 签到题 超级简单题吧,用max_score和max_name来计最大的名字和分数。 int n;scanf("%d",&n); int score,max_score; string name,max_name;对于一个新…

Windows修改Docker安装目录修改Docker镜像目录,镜像默认存储位置存放到其它盘

Windows安装Docker,默认是安装在C盘,下载镜像后会占用大量空间,这时需要调整镜像目录;场景:不想连服务器或者没有服务器,想在本地调试服务,该需求就非常重要。基于WSL2安装docker后,…

【Java】数组

目录 1.数组的定义与初始化 2.遍历数组 3.认识null 4.引用变量 5.返回多个值 6.数组拷贝 7.数组逆序 8.数组填充 9.小练习 //将整形数组转化为字符串 //二分查找优化 //冒泡排序优化 10.二维数组 //遍历二维数组 //不规则的二维数组 1.数组的定义与初始化 int…

了解国外SEO负面压制的现状与应对策略!

随着全球化的发展,越来越多的企业和品牌开始将目光转向海外市场,而谷歌作为全球最大的搜索引擎之一,也成为了外贸企业最主要的搜索引擎之一。 然而,随着谷歌的不断发展,国外SEO负面压制的现状也愈发严峻,外…

Android 9.0 Settings主菜单去掉自定义您的设备功能

1.前言 在9.0的系统rom定制化开发中,在系统Settings主页面一级菜单中,在开启护眼模式和改变系统密度的功能操作时,这时会发现在主菜单的网络菜单头部增加 自定义您的设备和设置护眼模式时间安排 等等相关的设置模块 这对于菜单布局显示相当不美观,产品要求不需要显示这些,…

SpringSecurity学习(四)密码加密、RememberMe记住我

文章目录密码加密一、简介密码为什么要加密常见的加密解决方案PasswordEncoder详解DelegatingPasswordEncoder二、自定义加密方式1. 使用灵活的密码加密方案(BCryptPasswordEncoder)加密验证(推荐)需要在密码前指定加密类型{bcryp…

Java学习笔记 --- Servlet(2)

一、HttpServletRequest类 1、基本介绍 每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。 然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletR…

渗透测试 | Email信息收集

0x00 免责声明 本文仅限于学习讨论与技术知识的分享,不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本文作者不为此承担任何责任,一旦造成后果请自行承担…

微服务保护(Sentinel)

1.雪崩微服务链路上某个服务出现了问题,结果导致整个微服务调用链上所有服务都出现了问题,这就是雪崩。2.解决雪崩问题的常见方式有四种1.超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等…

人工智能简单应用1-OCR分栏识别:两栏识别三栏识别都可以,本地部署完美拼接

大家好,我是微学AI,今天给大家带来OCR的分栏识别。 一、文本分栏的问题 在OCR识别过程中,遇到文字是两个分栏的情况确实是一个比较常见的问题。通常情况下,OCR引擎会将文本按照从左到右,从上到下的顺序一行一行地识别…

软考高项——信息文档管理

信息文档管理信息文档管理文档分类文档质量等级文档管理的规则和方法信息文档管理 信息文档管理的总线索包括: 1)文档分类 2)文档质量等级 3) 文档分类 1、开发文档 开发过程中用到的文档 (可行性报告、任书、需求、…

Django实践-06导出excel/pdf/echarts

文章目录Django实践-06导出excel/pdf/echartsDjango实践-06导出excel/pdf/echarts导出excel安装依赖库修改views.py添加excel导出函数修改urls.py添加excel/运行测试导出pdf安装依赖库修改views.py添加pdf导出函数修改urls.py添加pdf/生成前端统计图表修改views.py添加get_teac…

Qt读xml文件

QXmlStreamReaderQXmlStreamReader类通过简单的流式API为我们提供了一种快速的读取xml文件的方式。他比Qt自己使用的SAX解析方式还要快。所谓的流式读取即将一个xml文档读取成一系列标记的流,类似于SAX。而QXmlStreamReader类和SAX的主要区别就是解析这些标记的方式…

Linux自动化交互命令expect测试

介绍 expect 是由Don Libes基于Tcl(Tool Command Language )语言开发的,主要应用于自动化交互式操作的场景,借助Expect处理交互的命令,可以将交互过程如:ssh登录,ftp登录等写在一个脚本上&#…