浅析MySQL-基础篇01

news2024/11/25 4:19:21

执行一条select语句,发生了什么?

学习SQL的时候,查询数据的时候简单的用到就是下面的这SQL语句:

select * from tbl_1 where id = 100;

有没有想过,MYSQL执行一条select查询语句,在MYSQL中期间发生了什么?

带着这个问题,我们可以很好的理解MYSQL内部的架构,下面我们具体看看内部的流程。

MYSQL执行流程是怎么样的?

下面就是 MySQL 执行一条 SQL 查询语句的流程,也从图中可以看到 MySQL 内部架构里的各个功能模块

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

  • Server层负责建立连接、分析和执行SQL
  • 存储引擎负责数据的存储和求提取

第一步:连接器

如果你要使用MySQL,那么第一步是要先连接数据库服务,然后才能才能执行SQL语句。

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

连接的过程需要先经过TCP三次握手,因为MySQL是基于TCP协议进行传输。

 如何查看MySQL服务当前有多少个客户端连接?

可以执行执行下面的SQL命令进行查看

show processlist

上图结果:有两个用户名为root的用户连接了MYSQL服务,其中id为42的用户的Command状态为Sleep,这意味着该用户连接完MSQL服务就没有执行过任何命令,也就是个空闲的连接,空闲时长是81秒

 空闲连接会一直占用吗?

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

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

 一个处于空闲状态的连接被服务端主动断开后,这个客户端并不会马上知道,等到客户端再发起下一个请求的时候,才会收到"Lost connection"

 MySQL的连接数有限制吗?

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

MySQL的连接也有长连接和短连接的概念,区别如下:

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

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

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

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

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

两种解决方式:

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

数据库连接池简单的实现方式:

GitHub - maokeyang/SimpleDataSourcePool

至此,连接器的工作做完了,简单的总结一下:

  •  与客户端发起TCP三次握手建立连接
  • 校验客户端的用户名和密码
  • 如果校验通过,会读取用户的权限,然后后面的权限逻辑判断都会基于此时读到的权限

第二步:查询缓存

连接器的工作完成以后,客户端可以向MySQL服务发送SQL语句,服务端收到SQL语句后,就会解析SQL语句第一个字段,分析是什么类型的语句

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

其实缓存比较鸡肋。

对于更新比较频繁的表,查询缓存的命中率很低。因为只要表有一个更新操作,那么这个表的查询缓存就会被清空。如果刚缓存了一个查询结果很大的数据,还没被使用的时候,刚好这个表触发了更新操作,那么查询缓存就会被清空,相当于干了个寂寞。所以MySQL8.0版本中直接将查询缓存删掉了,也就是说从8.0版本开始,执行一条SQL查询语句,不会再走查询缓存这个阶段了。

第三步:解析SQL

 执行SQL之前,MySQL会先对SQL语句解析,这个工作交给「解析器」来处理

解析器

第一步:词法分析

关键字非关键字关键字非关键字
selectname

from

tbl_1

 

第二步:语法分析

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

第四步:执行SQL

经过解析器后,接着就要进入执行SQL查询语句的流程,每条select查询语句流程主要可以分为下面三个阶段

  • prepare阶段  -> 预处理阶段
  • optimize阶段 -> 优化阶段
  • execute阶段  -> 执行阶段
预处理器 

预处理都做了什么事情呢?

  • 检查SQL查询语句中的表或者字段是否存在
  • 将select * 中的*符号,扩展为表上的所有列
优化器

经过预处理阶段后,还需要为SQL查询语句先制定一个执行计划,这个工作是由「优化器」完成的。

优化器主要负责将SQL查询语句的执行方案确定下来,比如表里面有多个索引的时候,优化器会基于查询成本的考虑,来决定选择使用哪个索引

执行器

经历完优化器后,就确定了执行方案,接下来就真正开始执行语句了 ,这个工作是由「执行器」完成的。在执行的过程中,执行器就会和存储引擎交互了,交互是以记录为单位的。

以下以三种方式描述执行过程

  • 主键索引查询
  • 全表扫描
  • 索引下推

索引下推是MySQL5.6推出的查询优化策略,索引下推能够减少二级索引在查询时的回表操作,提高查询的效率,因为它将Server层部分负责的事情,交给存储引擎层去处理了。

下面以一个例子说明:

CREATE TABLE `tbl_score` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL comment '名字',
  `age` int NOT NULL comment '年龄',
  `score` int NOT NULL comment  '分数',
  PRIMARY KEY (`id`),
  KEY `index_age_score` (`age`,`score`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

下面这条查询语句:

select * from tbl_score  where age < 18 and score = 80;

联合索引当遇到范围查询就会停止匹配,也就是age字段能用到联合索引,但是score字段则无法利用到索引。

无索引下推(5.6版本之前)时,执行器与存储引擎的执行流程会如下:

  • Server层首先调用存储引擎的接口定位到满足条件的第一条二级索引记录,也就是定位到age<18的第一条记录;
  • 存储引擎根据二级索引的B+树快速定位到这条记录后,获取主键值,然后进行回表操作,将完整的记录返回给Server层;
  • Server层在判断该记录的score是否等于80,如果成立则将其发送给客户端;否则跳过该记录;
  • 接着,继续向存储引擎索要下一条记录,存储引擎在二级索引定位到记录后,获取主键值,然后回表操作,将完整的记录返回给 Server 层;
  • 如此往复,直到存储引擎把表中的所有记录读完。

可以看到,没有索引下推的时候,每查询到一条二级索引记录,都要进行回表操作,然后将记录返回给 Server,接着 Server 再判断该记录的 score 是否等于80。

使用索引下推时,执行器与存储引擎的执行流程:

  • Server层首先调用存储引擎的接口定位到满足条件的第一条二级索引记录,也就是定位到age<18的第一条记录;
  • 存储引擎定位到二级索引后,先不执行回表操作,而是先判断一下该索引中包含的列(score列)的条件(score 是否等于 80)是否成立。如果条件不成立,则直接跳过该二级索引。如果成立,则执行回表操作,将完成记录返回给 Server 层。
  • Server 层在判断其他的查询条件(本次查询没有其他条件)是否成立,如果成立则将其发送给客户端;否则跳过该记录,然后向存储引擎索要下一条记录。
  • 如此往复,直到存储引擎把表中的所有记录读完。

可以看到,使用了索引下推后,虽然 score 列无法使用到联合索引,但是因为它包含在联合索引(age,score)里,所以直接在存储引擎过滤出满足 score = 80 的记录后,才去执行回表操作获取整个记录。相比于没有使用索引下推,节省了很多回表操作。

如果发现执行计划里的 Extr 部分显示了 “Using index condition”,说明使用了索引下推。

 

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

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

相关文章

C/C++李峋同款跳动的爱心代码

一、写在前面 在编程的世界里&#xff0c;代码不仅仅是冷冰冰的命令&#xff0c;它也可以成为表达情感、传递浪漫的工具。今天&#xff0c;就让小编带着大家用C语言打造出李峋同款跳动的爱心吧&#xff01; 首先&#xff0c;我们需要知道C作为一种高级编程语言&#xff0c;拥…

Linux常用操作大全(上)

Linux常用操作 文章目录 Linux常用操作一、各类小技巧**1.ctrl c 强制停止****2.ctrl d 退出或登出**3.历史命令搜索4.光标移动快捷键5.清屏6.复制Ctrlshiftc7.粘贴Ctrlshiftv 二、软件安装1.概念2.yum与apt 三、systemctl控制服务四、软链接ln五、日期时区1.date查看日期2.修…

高阶数据结构[2]图的初相识

图的初相识 1.前言 2.图的概念 3.图的相关术语 4.图的存储结构 4.1邻接矩阵 4.2邻接表 4.3两种存储方式的对比 5.图的存储实现 5.1邻接矩阵的实现 5.2邻接表的实现 6.总结 1.前言 本章将大家学习数据结构中的“图”。有学习过离散数学的同学对这一章节或许会比…

和鲸科技执行总裁殷自强:面向空间数据协同分析场景的模型生命周期管理方法

导读&#xff1a; 由 ACM SIGSPATIAL 中国分会主办的第五届空间数据智能学术会议&#xff08;SpatialDI 2024&#xff09;于 2024 年 4 月 25 日- 27 日在南京圆满召开&#xff0c;主题为“ AGI 时代下的空间数据智能”&#xff0c;旨在深入推动空间数据智能研究的理论进步与应…

os实训课程模拟考试(8~13)

基于信号量的进程间通信 信号量IPC操作考查 编程要求 根据提示&#xff0c;在右侧编辑器补充代码&#xff0c;了解OpenEuler系统如何使用信号量进行IPC通信&#xff0c;代码中先用sem_read_array[]数组存储数据&#xff0c;并进行信号量与数据的输出&#xff0c;我们需要补充…

大数据与人工智能在保险行业数字化转型中的应用

随着科技的快速发展&#xff0c;大数据和人工智能&#xff08;AI&#xff09;技术在保险行业中扮演着越来越重要的角色&#xff0c;推动了保险行业的数字化转型。通过收集和分析海量的用户数据&#xff0c;利用先进的人工智能算法&#xff0c;保险公司能够更准确地评估风险&…

消息队列-概述-JMS和AMQP

JMS和AMQP JMS是什么 JMS&#xff08;JAVA Message Service,java 消息服务&#xff09;是 Java 的消息服务&#xff0c;JMS 的客户端之间可以通过 JMS 服务进行异步的消息传输。JMS&#xff08;JAVA Message Service&#xff0c;Java 消息服务&#xff09;API 是一个消息服务…

docker desktop for mac os如何使用本地代理

在macbook上弄了个代理&#xff0c;然后按照网上所说的去配代理 然后测试下 docker pull busybox 结果无反应&#xff0c;超时。我去&#xff01;&#xff01;&#xff01; 鼓捣了半天&#xff0c;看了docker官网&#xff0c;问了chatgpt &#xff0c;按照它们所说的试了下也没…

IDEA导入项目报错java程序包不存在

如图文件结构&#xff0c;本来是在web-demo中操作&#xff0c;但是想导入一下其他模块&#xff0c;切换了项目文件的目录&#xff0c;发现需要重新对Tomcat等进行配置&#xff0c;配置好之后发现运行出现Java相关错误&#xff08;如下&#xff09;记录一下修正过程。 java: 程序…

中国最著名的起名大师颜廷利:父亲节与之相关的真实含义

今天是2024年6月16日&#xff0c;这一天被广泛庆祝为“父亲节”。在汉语中&#xff0c;“父亲”这一角色常以“爸爸”、“大大”&#xff08;da-da&#xff09;或“爹爹”等词汇表达。有趣的是&#xff0c;“爸爸”在汉语拼音中表示为“ba-ba”&#xff0c;而当我们稍微改变“b…

消息队列-概述-什么是消息队列

什么是消息队列 我们可以把消息队列看作是一个存放消息的容器&#xff0c;当我们需要使用消息的时候&#xff0c;直接从容器中取出消息供自己使用即可。由于队列 Queue 是一种先进先出的数据结构&#xff0c;所以消费消息时也是按照顺序来消费的。 参与消息传递的双方称为 生产…

c++20 规范, vs2019 , 头文件 <mutex> ,注释以及几个探讨

&#xff08;1 探讨一&#xff09; mutex 这个名称的来源是 mutual exclusion &#xff1a;互相排斥。 mutex 与 recursive_mutex 的数据成员的定义如下&#xff1a; 测试如下&#xff1a; 运行以下&#xff1a; 以及&#xff1a; &#xff08;2 探讨二&#xff09; recursive_…

Orange Pi AIpro:高性能AI开发板开箱体验及样例测试

文章目录 前言背景介绍产品介绍主要参数配置AI处理器——昇腾310 NPU模型训练预测加载resnet50模型真实动物测试虚拟动物测试 前言 随着人工智能和物联网技术的迅速发展&#xff0c;单板计算机&#xff08;Single Board Computer, SBC&#xff09;在创客和开发者社区中越来越受…

buuctf-findKey

exe文件 运行发现这个窗口,没有任何消息 32位 进入字符串就发现了flag{ 左边红色代表没有F5成功 我们再编译一下(选中红色的全部按p) LRESULT __stdcall sub_401640(HWND hWndParent, UINT Msg, WPARAM wParam, LPARAM lParam) {int v5; // eaxsize_t v6; // eaxDWORD v7; /…

1055 集体照(测试点3, 4, 5)

solution 从后排开始输出&#xff0c;可以先把所有的学生进行排序&#xff08;身高降序&#xff0c;名字升序&#xff09;&#xff0c;再按照每排的人数找到中间位置依次左右各一个进行排列测试点3&#xff0c; 4&#xff0c; 5&#xff1a;k是小于10的正整数&#xff0c;则每…

Spring5中IOC创建对象的方式(有参与无参)与时机(附三类无参创建代码供参考)

Spring5中IOC创建对象的方式(有参与无参)附三类无参创建代码供参考 1. IOC容器 IOC是Spring框架的核心内容&#xff0c;Spring容器使用多种方式完美的实现了IOC&#xff0c;可以使用XML配置&#xff0c;也可以使用注解&#xff0c;新版本的Spring也可以零配置实现IOC。 Spri…

嵌入式微处理器重点学习(三)

堆栈操作 R1=0x005 R3=0x004 SP=0x80014 STMFD sp!, {r1, r3} 指令STMFD sp!, {r1, r3}是一条ARM架构中的存储多个寄存器到内存的指令,这里用于将r1和r3寄存器的内容存储到栈上。STMFD(Store Multiple Full Descending)是一种全递减模式的多寄存器存储指令,它会先将栈指针…

流媒体传输协议HTTP-FLV、WebSocket-FLV、HTTP-TS 和 WebSocket-TS的详细介绍、应用场景及对比

一、前言 HTTP-FLV、WS-FLV、HTTP-TS 和 WS-TS 是针对 FLV 和 TS 格式视频流的不同传输方式。它们通过不同的协议实现视频流的传输&#xff0c;以满足不同的应用场景和需求。接下来我们对这些流媒体传输协议进行剖析。 二、传输协议 1、HTTP-FLV 介绍&#xff1a;基于 HTTP…

MySQL-创建表~数据类型

070-创建表 create table t_user(no int,name varchar(20),gender char(1) default 男);071-插入数据 语法格式&#xff1a; insert into 表名(字段名1, 字段名2, 字段名3,......) values (值1,值2,值3,......);insert into t_user(no, name, gender) values(1, Cupid, 男);字…

嵌入式门槛高不高,工资怎么样?

一般来说&#xff0c;嵌入式岗位的准入门槛其实并不是特别高。通常情况下&#xff0c;只要能够熟练掌握 C 语言编程以及单片机相关知识&#xff0c;就能够去制作一些较为简单的电子产品&#xff0c;由此可见其门槛相对而言是比较低的&#xff0c;相应的薪水可能也不会特别高。 …