MySQL 内部组件结构以及SQL执行逻辑

目录

    • 一、MySQL的的内部组件结构
    • 二、连接器
    • 三、查询缓存
    • 四、分析器
    • 五、优化器
    • 六、执行器

一、MySQL的的内部组件结构

在这里插入图片描述

  • Server层
    • 主要包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数
      (如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
  • 存储引擎层
    • 存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在
      最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。也就是说如果我们在create table时不指定
      表的存储引擎类型,默认会给你设置存储引擎为InnoDB。

二、连接器

我们知道由于MySQL是开源的,他有非常多种类的客户端:navicat,mysql front,jdbc,SQLyog等非常丰富的客户端,这些
客户端要向mysql发起通信都必须先跟Server端建立通信连接,而建立连接的工作就是有连接器完成的。
第一步,你会先连接到这个数据库上,这时候接待你的就是连接器。连接器负责跟客户端建立连接、获取权限、维持和管
理连接。
连接命令一般是这么写的:

 mysql ‐h[数据库地址] ‐u[用户] ‐p[密码] ‐P[端口]

连接命令中的 mysql 是客户端工具,用来跟服务端建立连接。在完成经典的 TCP 握手后,连接器就要开始认证你的身份,
这个时候用的就是你输入的用户名和密码。

  • 1、如果用户名或密码不对,你就会收到一个"Access denied for user"的错误,然后客户端程序结束执行。

  • 2、如果用户名密码认证通过,连接器会到权限表里面查出你拥有的权限。之后,这个连接里面的权限判断逻辑,都将依赖于此时读到的权限,这就意味着,一个用户成功建立连接后,即使你用管理员账号对这个用户的权限做了修改,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。用户的权限表在系统表空间的mysql的user表中。

  • 3、连接完成后,如果你没有后续的动作,这个连接就处于空闲状态,你可以在 show processlist; 命令中看到它。文本中这个图是 show processlist; 的结果,其中的 Command 列显示为“Sleep”的这一行,就表示现在系统里面有一个空闲连接,客户端如果长时间不发送command到Server端,连接器就会自动将它断开。这个时间是由参数 wait_timeout 控制的,默认值是 8 小时,可以通过show global variables like "wait_timeout";查看。
    在这里插入图片描述
    在这里插入图片描述

  • 4、如果在连接被断开之后,客户端再次发送请求的话,就会收到一个错误提醒: Lost connection to MySQL server during
    query。这时候如果你要继续,就需要重连,然后再执行请求了

  • 5、数据库里面,长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。

  • 6、开发当中我们大多数时候用的都是长连接,把连接放在Pool内进行管理,但是长连接有些时候会导致 MySQL 占用内存涨得特别快,这是因为 MySQL 在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是 MySQL 异常重启了。
    怎么解决这类问题呢?

    • 定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连
    • 如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态

三、查询缓存

  • MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以
    key-value 对的形式,被直接缓存在内存中。key 是查询的语句,value 是查询的结果。如果你的查询能够直接在这个缓存中找到 key,那么这个 value 就会被直接返回给客户端。
  • 如果语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。你可以看到,如果查询命中缓存,MySQL 不需要执行后面的复杂操作,就可以直接返回结果,这个效率会很高。
  • 大多数情况查询缓存就是个鸡肋,因为查询缓存往往弊大于利。查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。因此很可能你费劲地把结果存起来,还没使用呢,就被一个更新全清空了。对于更新压力大的数据库来说,查询缓存的命中率会非常低,一般建议大家在静态表里使用查询缓存,什么叫静态表呢?就是一般我们极少更新的表。比如,一个系统配置表、字典表,那这张表上的查询才适合使用查询缓存。好在 MySQL 也提供了这种“按需使用”的方式。你可以将my.cnf参数query_cache_type 设置成 DEMAND。
my.cnf
#query_cache_type有3个值 0代表关闭查询缓存OFF1代表开启ON2DEMAND)代表当sql语句中有SQL_CACHE
#关键词时才缓存
query_cache_type=2
  • 可以通过 show global variables like "%query_cache_type%";查看是否开启缓存机制,默认是关闭的。
  • MySQL 8.0已经移除了查询缓存功能

四、分析器

  • 如果没有命中查询缓存,就要开始真正执行语句了。首先,MySQL 需要知道你要做什么,因此需要对 SQL 语句做解析。分析器先会做“词法分析”。你输入的是由多个字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串分别是什么,代表什么。
  • MySQL 从你输入的"select"这个关键字识别出来,这是一个查询语句。它也要把字符串“T”识别成“表名 T”,把字符
    串“ID”识别成“列 ID”。做完了这些识别以后,就要做“语法分析”。根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。如果你的语句不对,就会收到“You have an error in your SQL syntax”的错误提醒,比如下面这个语句 from 写成了"rom"。
mysql> select * fro test where id=1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds t
o your MySQL server version for the right syntax to use near 'fro test where id=1' at line 1

五、优化器

经过了分析器,MySQL 就知道你要做什么了。在开始执行之前,还要先经过优化器的处理,优化器是在表里面有多个索引的时候,决定使用哪个索引,或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。比如你执行下面这样的语句,这个语句是执行两个表的 join:

mysql> select * from test1 inner join test2 on test1.id=test2.id where test1.name=zhangsan and test2.name=lisi;
  • 既可以先从表 test1 里面取出 name=zhangsan 的记录的 ID 值,再根据 ID 值关联到表 test2,再判断 test2 里面 name的
    值是否等于 yangguo。
  • 也可以先从表 test2 里面取出 name=lisi 的记录的 ID 值,再根据 ID 值关联到 test1,再判断 test1 里面 name的值是否等于 zhangsan。
  • 这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。优化器阶段完成后,这个语句的执行方案就确定下来了,然后进入执行器阶段。如果你还有一些疑问,比如优化器是怎么选择索引的,有没有可能选择错等等。

六、执行器

开始执行的时候,要先判断一下你对这个表 T 有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示 (在
工程实现上,如果命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用 precheck 验证权
限)。

mysql> select * from test where id=1;
  • 如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。
    比如我们这个例子中的表 test 中,ID 字段没有索引,那么执行器的执行流程是这样的:
    • 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中;
    • 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
    • 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

至此,这个语句就执行完成了。对于有索引的表,执行的逻辑也差不多。第一次调用的是“取满足条件的第一行”这个接
口,之后循环取“满足条件的下一行”这个接口,这些接口都是引擎中已经定义好的。你会在数据库的慢查询日志中看到一个
rows_examined 的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加
的。在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟 rows_examined 并不是完全相同的。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法思想】贪心

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

Linux基础知识 总结

Linux基础知识 总结 1、Clion的简单介绍 CLion是以IntelliJ为基础,专为开发C及C所设计的跨平台IDE,可以在Windows、Linux及MacOS使用,这里我是在ubuntu 16.0.4基础上安装。2、下载 Linux版Clion的.tar.gz的压缩包 wget https://download.j…

这本书竟然把JAVA讲的如此透彻!漫画JAVA火爆出圈!

亲爱的粉丝们,你是否曾经为学习JAVA而苦恼?繁复的代码和复杂的逻辑常常让人感到头大。不过,今天我要为大家介绍一本神奇的书——《漫画JAVA》,它以图文并茂的方式,轻松诙谐地讲解了JAVA的方方面面。在这篇文章中&#…

【postgresql】ERROR: cannot alter type of a column used by a view or rule

修改字段类型 由varchar 改为int8。 具体sql alter table company alter column city_id type int8 using city_id::int8; 返回错误信息 > ERROR: cannot alter type of a column used by a view or rule DETAIL: rule _RETURN on view search_qy depends on column …

nodejs+vue 医院病历管理系统

系统使用权限分别包括管理员、病人和医生,其中管理员拥有着最大的权限,同时管理员的功能模块也是最多的,管理员可以对系统上所有信息进行管理。用户可以修改个人信息,对医院病历信息进行查询,对住院信息进行添加、修改…

【操作系统笔记十四】科普:POSIX 是什么

注:本文转载自该文章posix是什么都不知道,还好意思说你懂Linux? Linux开发者越来越多,但是仍然有很多人整不明白POSIX是什么。本文就带着大家来了解一下到底什么是POSIX,了解他的历史和重要性。 一、什么是 POSIX&…

RK3568驱动指南|第五期-中断-第44章 共享工作队列实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

Excel 语法

目录 语法 逐步创建公式 对单元格使用公式 另一个例子 语法 Excel中的一个公式用于进行数学计算。公式总是以单元格中键入的等号开头,然后是您的计算。 注意:您可以通过选择单元格并键入等号()来声明该单元格 逐步创建公式…

【Java 基础篇】Java 模块化详解

Java 9引入了一项重要的功能:模块化(Module System)。模块化是一种将代码和资源封装到可重用和独立的单元中的方法,它有助于改善代码的可维护性、可重用性和安全性。本文将介绍Java模块化的基本概念、如何创建和使用模块以及一些最…

基于微信小程序的美术馆预约平台设计与实现(源码+lw+部署文档+讲解等)

前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻…

SLAM从入门到精通(IMU参数的读取)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 上一篇文章我们说过,对于差速轮来说,旋转的计算很多程度上依赖于thetatan(theta)这个公式来进行的。但是,我们也…

以太坊代币标准ERC20、ERC165、ERC721

两个概念 ERC(Ethereum Request for Comment) 以太坊意见征集稿EIP(Ethereum Improvement Proposals)以太坊改进提案 ERC和EIP用于使得以太坊更加完善;在ERC中提出了很多标准,用的最多的标准就是它的Token标准; 有哪些标准详细见https://eips.ethereum…

中国TO B投资,迈入第二周期

2023年,中国TOB正在愈发成熟,迈进第二个周期的趋势已经体现在融资金额上。 作者|斗斗 编辑|皮爷 出品|产业家 TOB,依旧是一级市场的大热门。 统计数据显示,截止2023年8月31日,TOB领域共发生融资事件406起,同比2022年减少…

phpstudy2016 RCE漏洞验证

文章目录 漏洞描述漏洞验证 漏洞描述 PHPStudyRCE(Remote Code Execution),也称为phpstudy_backdoor漏洞,是指PHPStudy软件中存在的一个远程代码执行漏洞。 漏洞验证 打开phpstudy2016,用bp自带的浏览器访问www目录下…

Vue3+element-plus切换标签页时数据保留问题

记录一次切换标签页缓存失效问题,注册路由时name不一致可能会导致缓存失效

Unity中Shader通道ColorMask

文章目录 [TOC](文章目录) 前言一、ColorMask是用来干什么的二、怎么做到和 Unity UI 中的 Shader 一样根据UI层级自动适配Shader中模板测试值1、借鉴Unity官方的 UI Shader 前言 Unity中Shader通道ColorMask 一、ColorMask是用来干什么的 ColorMask RGB | A | 0 | R、G、B、…

雨课堂 运动与健康 网课参考资料

整理于网络:仅用于学习交流讨论,侵删 参考文档:https://www.doc88.com/p-99629779008847.html 参考视频: 运动与健康(2021年秋网课答案 69题版本)_哔哩哔哩 | https://www.bilibili.com/video/av210112837/…

WebGL 用鼠标控制物体旋转

目录 鼠标控制物体旋转 如何实现物体旋转 示例程序(RotateObject.js) 代码详解 示例效果 鼠标控制物体旋转 有时候,WebGL程序需要让用户通过鼠标操作三维物体。这一节来分析示例程序RotateObject,该程序允许用户通过拖动&…

DT 卡通材质学习 一

渐变着色器 相交线 笔刷和卡通结合使用 修改器

计算机类软件方向适合参加的比赛

前言 博主是一名计算机专业的大三学生,在校时候参加了很多比赛和训练营,现在给大家博主参加过的几个的比赛,希望能给大一大二的学生提供一点建议。 正文 最近也有比赛的,我会从时间线上来给大家推荐一些比赛,并且给…