MySQL性能优化——MYSQL执行流程

news2025/1/11 5:45:06

MySQL 执行流程1-5如下图。
在这里插入图片描述

MySQL 的架构共分为两层:Server 层和存储引擎层,

  • Server 层负责建立连接、分析和执行 SQL。MySQL 大多数的核心功能模块都在这实现,主要包括连接器,查询缓存、解析器、预处理器、优化器、执行器等。另外,所有的内置函数(如日期、时间、数学和加密函数等)和所有跨存储引擎的功能(如存储过程、触发器、视图等。)都在 Server 层实现。
  • 存储引擎层负责数据的存储和提取。支持 InnoDB、MyISAM、Memory 等多个存储引擎,不同的存储引擎共用一个 Server 层。现在最常用的存储引擎是 InnoDB,从 MySQL 5.5 版本开始, InnoDB 成为了 MySQL 的默认存储引擎。我们常说的索引数据结构,就是由存储引擎层实现的,不同的存储引擎支持的索引类型也不相同,比如 InnoDB 支持索引类型是 B+树 ,且是默认使用,也就是说在数据表中创建的主键索引和二级索引默认使用的是 B+ 树索引。

第一步:连接器,客户端和服务器端建立TCP连接

通过在命令行敲如下命令,开启mysql服务

mysql -h$ip -u$user -p$password

连接的过程需要先经过 TCP 三次握手,因为 MySQL 是基于 TCP 协议进行传输的,如果 MySQL 服务并没有启动,则会收到如下的报错:
在这里插入图片描述

如果 MySQL 服务正常运行,完成 TCP 连接的建立后,连接器就要开始验证你的用户名和密码,如果用户名或密码不对,就收到一个"Access denied for user"的错误,然后客户端程序结束执行。

如果用户密码都没有问题,连接器就会获取该用户的权限,然后保存起来,后续该用户在此连接里的任何操作,都会基于连接开始时读到的权限进行权限逻辑的判断。

所以,如果一个用户已经建立了连接,即使管理员中途修改了该用户的权限,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。

查看 MySQL 服务被多少个客户端连接了?

如果你想知道当前 MySQL 服务被多少个客户端连接了,你可以执行 show processlist 命令进行查看。
在这里插入图片描述

比如上图的显示结果,共有两个用户名为 root 的用户连接了 MySQL 服务,其中 id 为 6 的用户的 Command 列的状态为 Sleep ,这意味着该用户连接完 MySQL 服务就没有再执行过任何命令,也就是说这是一个空闲的连接,并且空闲的时长是 736 秒( Time 列)

空闲连接会一直占用着吗?

MySQL 定义了空闲连接的最大空闲时长,由 wait_timeout 参数控制的,默认值是 8 小时(28880秒),如果空闲连接超过了这个时间,连接器就会自动将它断开。

mysql> show variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+
1 row in set (0.00 sec)

当然,我们自己也可以手动断开空闲的连接,使用的是 kill connection + id 的命令。

mysql> kill connection +6;
Query OK, 0 rows affected (0.00 sec)

一个处于空闲状态的连接被服务端主动断开后,这个客户端并不会马上知道,等到客户端在发起下一个请求的时候,才会收到这样的报错“ERROR 2013 (HY000): Lost connection to MySQL server during query”。

MySQL 的连接数有限制吗?

MySQL 服务支持的最大连接数由 max_connections 参数控制,比如我的 MySQL 服务默认是 151 个,超过这个值,系统就会拒绝接下来的连接请求,并报错提示“Too many connections”。

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+
1 row in set (0.00 sec)

MySQL 的连接也跟 HTTP 一样,有短连接和长连接的概念,它们的区别如下:

// 短连接
连接 mysql 服务(TCP 三次握手)
执行sql
断开 mysql 服务(TCP 四次挥手)

// 长连接
连接 mysql 服务(TCP 三次握手)
执行sql
执行sql
执行sql
....
断开 mysql 服务(TCP 四次挥手)

可以看到,使用长连接的好处就是可以减少建立连接和断开连接的过程,所以一般是推荐使用长连接。

但是,使用长连接后可能会占用内存增多,因为 MySQL 在执行查询过程中临时使用内存管理连接对象,这些连接对象资源只有在连接断开时才会释放。如果长连接累计很多,将导致 MySQL 服务占用内存太大,有可能会被系统强制杀掉,这样会发生 MySQL 服务异常重启的现象。

怎么解决长连接占用内存的问题?

有两种解决方式。

第一种,定期断开长连接。既然断开连接后就会释放连接占用的内存资源,那么我们可以定期断开长连接。

第二种,客户端主动重置连接。MySQL 5.7 版本实现了 mysql_reset_connection() 函数的接口,注意这是接口函数不是命令,那么当客户端执行了一个很大的操作后,在代码里调用 mysql_reset_connection 函数来重置连接,达到释放内存的效果。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。

第二步:查询缓存,如果是SELECT语句就查缓存

建立连接后,客户端向 MySQL 服务发送 SQL 语句,MySQL 服务收到 SQL 语句后,就会解析出 SQL 语句的第一个字段,看看是什么类型的语句

如果 SQL 是查询语句(select 语句),MySQL 就会先去查询缓存( Query Cache )里查找缓存数据,看看之前有没有执行过这一条命令,这个查询缓存是以 key-value 形式保存在内存中的,key 为 SQL 查询语句,value 为 SQL 语句查询的结果。

如果查询的语句命中查询缓存,那么就会直接返回 value 给客户端。如果查询的语句没有命中查询缓存中,那么就要往下继续执行,等执行完后,查询的结果就会被存入查询缓存中。

为什么mysql8.0没有查询缓存功能

但是对于更新比较频繁的表,查询缓存的命中率很低的,因为只要一个表有更新操作,那么这个表的查询缓存就会被清空。如果刚缓存了一个查询结果很大的数据,还没被使用的时候,刚好这个表有更新操作,查询缓冲就被清空了,相当于缓存了个寂寞。

所以,MySQL 8.0 版本直接将查询缓存删掉了,也就是说 MySQL 8.0 开始,执行一条 SQL 查询语句,不会再走到查询缓存这个阶段了。

对于 MySQL 8.0 之前的版本,如果想关闭查询缓存,我们可以通过将参数 query_cache_type 设置成 DEMAND。

TIP
这里说的查询缓存是 server 层的,也就是 MySQL 8.0 版本移除的是 server 层的查询缓存,并不是 Innodb 存储引擎中的 buffer pool。

第3步:解析 SQL

在正式执行 SQL 查询语句之前, MySQL 会先对 SQL 语句做解析
解析器会做如下两件事情。

词法分析

第一件事情,词法分析。MySQL 会根据你输入的字符串识别出关键字出来,例如,SQL语句 select username from userinfo,在分析之后,会得到4个Token,其中有2个Keyword,分别为select和from:

关键字 非关键字 关键字 非关键字
select username from userinfo
第二件事情,语法分析。根据词法分析的结果,语法解析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法,如果没问题就会构建出 SQL 语法树,这样方便后面模块获取 SQL 类型、表名、字段名、 where 条件等等。

img

如果我们输入的 SQL 语句语法不对,就会在解析器这个阶段报错。比如,我下面这条查询语句,把 from 写成了 form,这时 MySQL 解析器就会给报错。

但是注意,表不存在或者字段不存在,并不是在解析器里做的,《MySQL 45 讲》说是在解析器做的,但是经过我和朋友看 MySQL 源码(5.7和8.0)得出结论是解析器只负责检查语法和构建语法树,但是不会去查表或者字段存不存在。

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

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

相关文章

简单易上手,亚马逊云科技Amazon CodeWhisperer个性化辅助功能成为开发者好帮手

Amazon CodeWhisperer介绍 Amazon CodeWhisperer是亚马逊云科技出品的一款基于机器学习的通用代码生成器,可实时提供代码建议。类似Cursor和Github Copilot编码工具。在编写代码时,它会自动根据您现有的代码和注释生成建议。从单行代码建议到完整的函数&…

离线版IP归属地查询

这里简单介绍一下Ip2regionSearcher是什么? ip2region 是准确率 99.9% 的 IP 地址定位库,0.0x毫秒级查询,提供了 Java、PHP、C、Python、Node.js、Golang、C#、Rust、Lua的查询绑定和 Binary、B树、内存三种查询算法! Setp1&…

【基于MBD开发模式的matlab持续集成(一)】

基于MBD开发模式的matlab持续集成 引言 或许是感受到行业内卷的愈加激烈,在传统制造和高新技术相结合的新能源领域对软件工程开发的要求也愈加提高,尤其在互联网已经大行 其道的敏捷开发,便顺其自然的被新能源的老板们所看重。 概述 本文…

moea项目的问题解决方案

报错1: (moea) aaaASUS:~/ML/paper/APG-SMOEA/code$ sh test.sh python: cant open file /home/aaa/ML/paper/APG-SMOEA/code/run_GAN-adjlvxm.py: [Errno 2] No such file or directory Finish GAN-adjlvxm on 1修改了run_benchmark.sh的line22->line23 报错2…

android去掉 原生锁屏

1. /frameworks/base/core/java/com/android/internal/widget/LockPatternUtils.java 直接 return true 2./packages/apps/Settings/src/com/android/settings/password/ScreenLockType.java 都改成 none 类型

JVM——9.对象的访问定位方式

前一篇文章,我们详细的了解了对象在堆内存中是如何分配的。现在,对象已经分配好了,那么要如何访问定位呢?下面,我们一起来了解一下。 目录 1.概述 2.句柄法 3.直接指针法 4.小结 1.概述 创建对象是为了使用该对象…

Lnmp架构之mysql数据库实战1

1、mysql数据库编译 编译成功 2、mysql数据库初始化 配置数据目录 全局文件修改内容 生成初始化密码并进行初始化设定 3、mysql主从复制 什么是mysql的主从复制? MySQL的主从复制是一种常见的数据库复制技术,用于将一个数据库服务器(称为主…

MyBatisPlus(四)表映射:@TableName

表映射 数据库中的表名,和项目中的实体类名,并不相同,则需要通过注解TableName来进行映射。 未映射前报错示例 数据库表名:tb_user 实体类名:User 测试代码 Autowiredprivate UserMapper userMapper;Testvoid selec…

git 工作区和版本库和暂存区差异比较

一般比较代码差距习惯用Beyond Compare进行比较,然后进行一些定位和解bug操作,现使用了git 工具进行代码比较. (1)比较两个版本库之间的差距 git log 得到commit SHA git diff SHA1 SHA2 (2)比较工作区和版本库差异 git diff HEAD 或 git log git …

计算机网络分类

按照覆盖范围分类 (1)个域网:通常覆盖范围在1~10m。 (2)局域网:通常覆盖范围在10m~1km。 (3)城域网:覆盖范围通常在5~50 km 。 &…

程序安全漏洞

一、SQL注入 一种代码注入技术,一般被应用于攻击web应用程序。 通过在web应用接口传入一些特殊参数字符,来欺骗应用服务器,执行恶意的SQL命令,以达到非法获取系统信息的目的。它目前是黑客对数据库进行攻击的最常用手段之一。 常…

【线性回归、岭回归、Lasso回归分别预测患者糖尿病病情】数据挖掘实验一

Ⅰ、项目任务要求 任务描述:将“diabetes”糖尿病患者数据集划分为训练集和测试集,利用训练集分别结合线性回归、岭回归、Lasso回归建立预测模型,再利用测试集来预测糖尿病患者病情并验证预测模型的拟合能力。具体任务要求如下: …

服务网格和微服务架构的关系:理解服务网格在微服务架构中的角色和作用

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…

现在进入广告行业好做吗?

广告行业真的很好,大家快来…… 在这里你可以无限发挥你的创意和想象力,有趣的同事,不刻板的工作内容,与爱豆合作,偶尔见见明星,出入城市CBD,一身名牌,精美PPT挥斥方遒,…

grafana结合Skywalking追踪Trace(一)

SW应用中对Trace的跟踪一直占有重要的地位,即可以用户指定的tag值,可以筛选出感兴趣的trace(跟踪链),用户可以通过跟踪链追踪各个Span的详细情况。 但是在使用SW OAP原生页面中会存在两个问题: 1) Trace数量太多了&…

Linux Ubuntu命令行快速配置C++开发环境

本文介绍在Linux操作系统的Ubuntu版本中,基于命令行,快速配置C 编辑、编译、运行的代码开发环境的简便方法。 在之前的文章Linux操作系统Ubuntu 22.04配置Visual Studio Code与C代码开发环境的方法(https://blog.csdn.net/zhebushibiaoshifu/article/det…

Springboot项目升级2.2.x升至2.7.x

依赖管理 spring-boot-starter-parent 升级为2.7.1 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId> <!-- 升级为2.7.x的版本--><version>2.7.1</version>…

【STM32】WWDG—窗口看门狗

在一个设定好的区间进行喂狗 与独立看门狗不同的是&#xff0c;独立看门狗只需要在计时到0之前喂狗。而窗口看门狗需要在设定好的区间内进行喂狗&#xff0c;否则进行reset。 下限 递减计数器不断的往下递减计数&#xff0c;当减到一个固定值 0X40时还不喂狗的话&#xff0c…

《ADS2011射频电路设计与仿真实例》功率放大器设计的输入输出匹配

徐兴福这本书的6.6 Smith圆图匹配这一节中具体匹配时&#xff0c;直接给出了电容与串联微带的值&#xff0c;没有给出推导过程&#xff0c;我一开始以为是省略了详细推导过程&#xff0c;后来发现好像基本上是可以随便自己设的。以输入匹配&#xff08;书本6.6.4输入匹配电路的…

​安徽农业大学《乡村振兴战略下传统村落文化旅游设计》许少辉博士新著——2023学生开学季辉少许流动站

​安徽农业大学《乡村振兴战略下传统村落文化旅游设计》许少辉博士新著——2023学生开学季辉少许流动站