MySQLExplain详解

news2025/1/11 9:55:33

Explain使用场景

  1. 查询性能优化:EXPLAIN可以帮助开发者分析查询语句的执行计划,判断是否有效地使用了索引、是否有可能导致全表扫描等性能问题。通过EXPLAIN的输出,可以找到潜在的性能瓶颈,并优化查询语句、创建合适的索引或调整表结构,以提高查询性能和效率。

  2. 确认索引使用情况:使用EXPLAIN可以确认MySQL是否使用了预期的索引来执行查询。如果没有使用预期的索引,可能需要重新优化查询语句或调整索引的定义。

  3. 查看查询执行顺序:EXPLAIN可以显示查询的执行顺序,包括子查询、连接操作等。通过查看执行顺序,可以了解查询的复杂度,从而判断是否需要优化查询或拆分查询成多个简单查询。

  4. 查询执行效率比较:通过EXPLAIN可以比较不同查询语句的执行计划,找到最优的查询方案,以提高查询效率。

  5. 监控查询性能:结合MySQL的慢查询日志,可以使用EXPLAIN来监控和分析慢查询,找出慢查询的原因,进一步优化和改进查询性能。

  6. 了解索引使用情况:EXPLAIN可以展示查询的可能索引和实际使用的索引,通过比较可以了解索引是否有效,是否需要重新设计索引或增加新的索引。

Explain分析示例

官方文档:MySQL 5.7 Explain参考手册

假设有以下查询语句:

EXPLAIN SELECT * FROM order WHERE order_status = 'SHIPPED' AND order_date >= '2023-01-01';

通过执行EXPLAIN命令来分析上述查询语句的执行计划,可以得到类似以下的输出:

+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| 1  | SIMPLE      | order | ref  | order_status  | order_status | 4     |      | 1000 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+

接下来解释上述输出中的各个字段:

  • id: 查询的标识符,每个查询都有一个唯一的ID,对于简单查询,通常为1。

  • select_type: 查询的类型,这里是SIMPLE,表示简单查询。

  • table: 表名,表示查询涉及的表,这里是orders表。

  • type: 访问类型,表示MySQL如何访问表,这里是ref,表示使用非唯一索引进行等值查询。

  • possible_keys: 表示可能使用的索引,这里是order_status,表示可能使用order_status字段上的索引。

  • key: 实际使用的索引,这里是order_status,表示实际使用了order_status字段上的索引。

  • key_len: 表示索引字段的长度,这里是4,表示order_status字段的长度为4个字节。

  • ref: 表示与索引一起使用的字段或常量,这里为空,表示没有与索引一起使用的字段。

  • rows: 估计查询返回的行数,这里是1000,表示该查询可能返回1000行结果。

  • Extra: 附加信息,这里是Using where,表示使用了WHERE条件进行过滤。

通过上述EXPLAIN输出,可以得到以下分析结论:

  1. 查询使用了名为order_status的非唯一索引,可以提高查询性能。
  2. 查询使用了WHERE条件进行过滤,过滤条件为order_status字段等于'SHIPPED'和order_date字段大于等于'2023-01-01'。
  3. 查询可能返回约1000行结果。
  4. 在查询中的每个表会输出一行,如果有两个表通过 join 连接查询,那么会输出两行。

Explain字段含义

示例表结构

 monitor_main表结构:


CREATE TABLE `monitor_main` (
  `id` bigint(30) NOT NULL AUTO_INCREMENT,
  `index_id` bigint(30) DEFAULT NULL,
  `code` varchar(100) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  `function` varchar(100) DEFAULT NULL,
  `start_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `end_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `value` bigint(30) DEFAULT NULL,
  `created_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `updated_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_value` (`value`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2711 DEFAULT CHARSET=utf8mb4;

monitor_map表结构:


CREATE TABLE `monitor_map` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `main_id` bigint(20) DEFAULT NULL,
  `map` varchar(255) DEFAULT NULL,
  `mapkey` varchar(255) DEFAULT NULL,
  `mapvalue` varchar(255) DEFAULT NULL,
  `created_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `updated_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_main_id` (`main_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2914 DEFAULT CHARSET=utf8mb4;

Explain中的列 

  

id列

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

select_type列

select_type表示对应行是简单还是复杂的查询。

  • simple:简单查询,查询不包含子查询和union。

  • primary:复杂查询中最外层的select。

  • subquery:包含在select 中的子查询(不在from子句中)。

  • derived:包含在from子句中的子查询,MySQL会将结果存放在一个临时表中,也称为派生表。

  • UNION: UNION操作。

table列

        这一列表示Explain的一行正在访问哪个表,当from子句中有子查询时,table列是格式,表示当前查询依赖id=N的查询,于是先执行id=N的查询。

type列

        这一列表示关联类型或访问类型 ,即MySQL决定如何查找表中的行,查找数据行记录的大概范围,依次从最优到最差分别为:system > const > eq_ref > ref > range > index > ALL,一般来说,得保证查询达到range级别,最好达到ref。

  • NULL:MySQL能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引。例如:在索引列中选取最小值,可以单独查找索引来完成,不需要在执行时访问表。


EXPLAIN SELECT min(monitor_main.id) FROM monitor_main;
  • const, system:MySQL能对查询的某部分进行优化并将其转化成一个常量。用于primary key或unique key的所有列与常数比较时,所以表最多有一个匹配行,读取1次,速度比较快。system是const的特例 ,表里只有一条数据匹配时为system。


EXPLAIN SELECT * FROM monitor_main WHERE monitor_main.id=``2400``;
  • eq_ref:primary key 或unique key索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录,这可能是在const之外最好的连接类型了,简单的select查询不会出现这type。


EXPLAIN SELECT * FROM monitor_main LEFT JOIN monitor_map on monitor_main.id=monitor_map.id;
  • ref:相比eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行,简单select查询,monitor_main.value是普通索引(非唯一索引)。


EXPLAIN SELECT * FROM monitor_main WHERE monitor_main.value=``1400``;
  • range:范围扫描通常出现在in(),between ,> ,<,>=等操作中,使用一个索引来检索给定范围的行。


EXPLAIN SELECT * FROM monitor_main WHERE monitor_main.id>``2520``;
  • index:扫描全索引就能拿到结果,一般是扫描某个二级索引,这种扫描不会从索引树根节点开始快速查找,而是直接对二级索引的叶子节点遍历和扫描,速度还是比较慢的,这种查询一般为使用覆盖索引,二级索引一般比较小,所以这种通常比ALL快一些。


EXPLAIN SELECT monitor_main.value FROM monitor_main;
  • ALL:即全表扫描,扫描你的聚集索引的所有叶子节点,通常情况下这需要增加索引来进行优化了。


EXPLAIN SELECT * FROM monitor_main;

possible_keys列

        这一列显示查询可能使用哪些索引来查找。Explain时可能出现possible_keys有列,而key显示NULL的情况,这种情况是因为表中数据不多,MySQL认为索引对此查询帮助不大,选择了全表查询,如果该列是NULL,则没有相关的索引,在这种情况下,可以通过检查where子句看是否可以创造一个适当的索引来提高查询性能,然后用Explain查看效果。

key列

这一列显示MySQL实际采用哪个索引来优化对该表的访问,如果没有使用索引,则该列是NULL,如果想强制MySQL使用possible_keys列中的索引,在查询中使用force index。

key_len列

这一列显示了MySQL在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。

key_len计算规则如下:

  • 字符串:char(n):如果存汉字长度就是3n字节 ;varchar(n):如果存汉字则长度是3n+2字节,加的2字节用来存储字符串长度,因为varchar是变长字符串。

  • 数值类型:tinyint: 1字节 smallint:2字节 int:4字节 bigint:8字节

  • 时间类型:date: 3字节 timestamp:4字节 datetime:8字节

  • 如果字段允许为 NULL,需要1字节记录是否为 NULL 索引最大长

  • 索引最大长度是768字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索 引。

ref列

        这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量)。

rows列

        这一列是MySQL估计要读取并检测的行数,注意这个不是结果集里的行数。

Extra列

这一列展示的是额外信息。

  • Using index:使用覆盖索引,MySQL执行计划Explain结果里的key有使用索引,如果select后面查询的字段都可以从这个索引的树中获取,这种情况一般可以说是用到了覆盖索引,extra里一般都有Using index;覆盖索引一般针对的是辅助索引,整个查询结果只通过辅助索引就能拿到结果,不需要通过辅助索引树找到主键,再通过主键去主键索引树里获取其它字段值。

  • Using where:使用where语句来处理结果,并且查询的列未被索引覆盖。

  • Using filesort:将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序。这种情况下一般也是要考虑使用索引来优化的。 

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

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

相关文章

Win11虚拟机安装并使用

windows11 虚拟机安装 操作如下&#xff1a;1.进入微软官网2.打开虚拟机应用创建新虚拟机3.选择刚下载IOS文件4 设置虚拟机磁盘空间大小&#xff0c;这个数字可以随便写&#xff0c;反正都是虚拟的&#xff0c;但不可以低于64GB。下面的是否拆分磁盘文件&#xff0c;可更具需要…

大数据课程C4——ZooKeeper结构运行机制

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 了解Zookeeper的特点和节点信息&#xff1b; ⚪ 掌握Zookeeper的完全分布式安装 ⚪ 掌握Zookeeper的选举机制、ZAB协议、AVRO&#xff1b; 一、Zookeeper-简介 1. 特点…

【计网】什么是三次握手四次挥手

文章目录 1、什么是TCP2、什么是TCP连接2.1、连接概念2.2、如何唯一确定一个TCP连接2.3、TCP最大连接数 3、三次握手3.1、为什么需要三次握手3.2、三次握手过程3.3、为什么一定是三次3.3.1、避免历史连接3.3.2、同步双方初始序列号3.3.3、避免资源浪费3.3.4、总结 3.4、握手丢失…

vue实现卡牌数字动态翻牌效果

vue实现卡牌数字动态翻牌效果 1. 实现效果2. 实现代码 1. 实现效果 在大屏项目中&#xff0c;我们尝尝会遇到卡牌式数字显示且能动态翻牌的效果&#xff0c;效果图如下&#xff1a; 2. 实现代码 <template><div class"days-box"><div class"op…

初探PID—速度闭环控制

由于在调PID时意外把板子烧了&#xff0c;目前只完成了比例调节的调试&#xff0c;整个程序也不太完善&#xff0c;本文当前仅作记录&#xff0c;后续会完善更改。 ——2023.07.26 文章目录 一、什么是PID二、PID有什么用三、PID程序实现 一、什么是PID PID是常用的一种控制算…

windows默认编码格式修改

1.命令提示符界面输入 chcp 936 对应 GBK 65001 对应 UTF-8 2.临时更改编码格式 chcp 936(或65001) 3.永久更改编码格式 依次开控制面板->时钟和区域->区域->管理->更改系统区域设置&#xff0c;然后按下图所示&#xff0c;勾选使用UTF-8语言支持。然后重启电脑。此…

上门小程序开发|上门服务小程序|上门家政小程序开发

随着移动互联网的普及和发展&#xff0c;上门服务成为了许多人生活中的一部分。上门小程序是一种基于小程序平台的应用程序&#xff0c;它提供了上门服务的在线平台&#xff0c;为用户提供了便捷的上门服务体验。下面将介绍一些适合开发上门小程序的商家。   家政服务商家&am…

帮助中心内容需要囊括什么?(内含案例分享)

给产品制作一个帮助中心&#xff0c;让用户能够通过访问帮助中心查看产品相关内容&#xff0c;尽快了解产品&#xff0c;熟悉操作。不仅仅局限于售后&#xff0c;在售中售前都能够发挥很大的作用&#xff0c;帮助用户全面了解产品&#xff0c;减少销售的工作量&#xff0c;节约…

数字孪生和 GIS 系统融合将为水利领域带来哪些变化?

随着科技的不断进步&#xff0c;数字孪生和 GIS 系统的融合应用逐渐成为了水利领域的新趋势。数字孪生是指通过数字化技术模拟物理实体和过程&#xff0c;将现实世界与虚拟世界相结合的技术&#xff0c;而 GIS 系统则是地理信息系统&#xff0c;用于收集、存储、管理和分析地理…

Mybatis快速入门,Mybatis的核心配置文件

Mybatis快速入门 一、Mybatis简介1.1Mybatis简化JDBC 二、Mybatis快速入门2.1创建user表&#xff0c;添加数据2.2创建模块&#xff0c;导入坐标2.3编写Mybatis核心配置文件 --> 替换连接信息&#xff0c;解决硬编码问题2.4编写SQL映射文件 --> 统一管理sql语句&#xff0…

7、Java入门教程【面向对象】

面向对象是Java编程的核心概念&#xff0c;如果不能充分了解面向对象的思想&#xff0c;那么会给你在实际的项目开发过程中&#xff0c;带来很多业务设计上的困扰。 一、构造器 我们在设计完一个类&#xff0c;在使用这个类去创建对象实例的时候&#xff0c;有些场景是需要对…

云曦暑期学习第二周——文件上传漏洞

1.文件上传 1.1原理 一些web应用程序中允许上传图片、视频、头像和许多其他类型的文件到服务器中。 文件上传漏洞就是利用服务端代码对文件上传路径变量过滤不严格将可执行的文件上传到一个到服务器中 &#xff0c;再通过URL去访问以执行恶意代码。 1.2为什么存在文件上传漏…

4-Linux组管理和权限管理

Linux组管理和权限管理 Linux组的基本介绍文件/目录的所有者组的创建文件/目录所在的组其它组改变用户所在的组权限的基本介绍第0-9位说明rwx权限详解rwx 修饰文件时rwx修饰目录时 修改权限第一种方式&#xff1a;、-、 变更权限第二种方式&#xff1a;通过数字变更权限 修改文…

第26天-秒杀服务(秒杀系统设计与实现)

1.秒杀设计 1.1.秒杀业务 秒杀具有瞬间高并发特点&#xff0c;针对这一特点&#xff0c;必须要做限流异步缓存&#xff08;页面静态化&#xff09;独立部署。 限流方式&#xff1a; 前端限流&#xff0c;一些高并发的网站直接在前端页面开始限流&#xff0c;例如&#xff1a…

web-文件包含

产生原因&#xff1a; 开发人员都希望代码更加灵活&#xff0c;所以通常会将被包含的文件设置为变量&#xff0c;用来进行动态调用。正是这种灵活性&#xff0c;从而导致客户端可以调用一个恶意文件&#xff0c;造成文件包含漏洞。 实际上被包含文件可以是任意格式的&#xff0…

【数据结构】带你轻松拿捏顺序表(内附源码)

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;今天正式开始开新坑啦&#xff01;在接下来的这一个月来我会逐步带大家了解初阶数据结构的知识&#xff0c;如果是你主修的是计算机专业数据结构的重要性不言而喻&…

深度学习论文: Q-YOLO: Efficient Inference for Real-time Object Detection及其PyTorch实现

深度学习论文: Q-YOLO: Efficient Inference for Real-time Object Detection及其PyTorch实现 Q-YOLO: Efficient Inference for Real-time Object Detection PDF: https://arxiv.org/pdf/2307.04816.pdf PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代…

LeetCode 918. Maximum Sum Circular Subarray【数组,动态规划】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

215.数组中的第K个最大元素-C++

题目来源&#xff1a;力扣 题目描述&#xff1a; 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法…

Java书签 #解锁MyBatis的4种批量插入方式及ID返回姿势

1. 今日书签 项目开发中&#xff0c;我们经常会用到单条插入和批量插入。但是实际情况可能是&#xff0c;项目初期由于种种原因&#xff0c;在业务各处直接使用单条插入SQL进行开发&#xff08;未开启批处理&#xff09;&#xff0c;在后面的迭代中&#xff0c;系统性能问题渐…