MYSQL 四、mysql进阶 1(mysql逻辑架构以及查询流程)

news2024/11/26 4:49:48

        一、mysql的逻辑架构

         1. 逻辑架构剖析

         1.1 服务器处理客户端请求

         mysql是典型的c/s架构,即 client/server 架构,不论是客户端进程和服务器进程是采用哪种方式进行通信,最后实现的效果都是:客户端进程向服务器进程发送一段文本(sql语句),服务器进程处理后再向客户端进程发送一段文本(处理结果)

        

        下面具体展开看一下:

        
         Connectors:
        指的是不同语言中与sql的交互,mysql首先是一个网络程序,在tcp之上定义了自己的应用层协议,所以要使用mysql,我们可以编写代码,即mysql server 建立tcp连接,之后按照其定义好的协议进行交互。或者比较方便的方法是调用sdk,比如    native C API、JDBC、PHP等各语言mysql connector,或者通过ODBC,但通过sdk来访问mysql,本质上还是在tcp连接上通过mysql协议跟mysql进行交互。        
        
        mysql结构可以分为一下三层:
        第1层:连接层 
        Mysql服务器之外的客户端程序(与具体的语言有关),像java使用JDBC连接。

        系统(客户端)访问 MySQL 服务器前,做的第一件事就是建立 TCP 连接。
        经过三次握手建立连接成功后,
MySQL 服务器对 TCP 传输过来的账号密码做身份认证、权限获取。

  • 用户名或密码不对,会收到一个Access denied for user错误,客户端程序结束执行
    赖于此时读到的权限
  • 用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑,都将依

        思考一个问题:一个系统只会和mysql服务器建立一个连接么?只能有一个系统和mysql服务器建立连接么?
        当然不是,多个系统哦都可以和mysql服务器建立连接,每个系统建立的连接肯定不止一个,所以,为了解决tcp无限创建与tcp频繁连创建销毁带来的资源耗尽,性能下降问题,mysql服务器里有专门的tcp连接池限制连接数,采用长连接模式服务tcp连接,来解决上述问题

        TCP 连接收到请求后,必须要分配给一个线程专门与这个客户端的交互。所以还会有个线程池,去走后面的流程。每一个连接从线程池中获取线程,省去了创建和销毁线程的开销。

         2层:服务层

  • SQL Interface: SQL接口
    • 接收用户的SQL命令,并且返回用户需要查询的结果。比如SELECT ... FROM就是调用SQL Interface
    • MySQL支持DML(数据操作语言)、DDL(数据定义语言)、存储过程、视图、触发器、自定义函数等多种SQL语言接口
  • Parser: 解析器
    • 在解析器中对 SQL 语句进行语法分析、语义分析。将SQL语句分解成数据结构,并将这个结构传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的。如果在分解构成中遇到错误,那么就说明这个SQL语句是不合理的。
    • 在SQL命令传递到解析器的时候会被解析器验证和解析,并为其创建 语法树 ,并根据数据字典丰富查询语法树,会 验证该客户端是否具有执行该查询的权限 。创建好语法树后,MySQL还会对SQl查询进行语法上的优化,进行查询重写。
  • Optimizer: 查询优化器
    • SQL语句在语法解析之后、查询之前会使用查询优化器确定 SQL 语句的执行路径,生成一个执行计划
    • 这个执行计划表明应该 使用哪些索引 进行查询(全表检索还是使用索引检索),表之间的连接顺序如何,最后会按照执行计划中的步骤调用存储引擎提供的方法来真正的执行查询,并将查询结果返回给用户。
    • 它使用选取-投影-连接 策略进行查询。例如:
SELECT id,name FROM student WHERE gender = ' ' ;
                这个SELECT查询先根据 WHERE 语句进行 选取 ,而不是将表全部查询出来以后再进行 gender 过 滤。 这个SELECT 查询先根据 id name 进行属性 投影 ,而不是将属性全部取出以后再进行过滤,将这两个查询条件 连接 起来生成最终查询结果。
  • Caches & Buffers: 查询缓存组件
    • MySQL内部维持着一些CacheBuffer,比如Query Cache用来缓存一条SELECT语句的执行结果,如果能够在其中找到对应的查询结果,那么就不必再进行查询解析、优化和执行的整个过程了,直接将结果反馈给客户端。
    • 这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等
    • 这个查询缓存可以在 不同客户端之间共享
    • MySQL 5.7.20开始,不推荐使用查询缓存,并在 MySQL 8.0中删除

        第3 层:引擎层
        插件式存储引擎层( Storage Engines ), 真正的负责了 MySQL 中数据的存储和提取,对物理服务器级别 维护的底层数据执行操作 ,服务器通过 API 与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要进行选取。
        MySQL 8.0.25默认支持的存储引擎如下:
        
        
        存储层:
        所有的数据,数据库、表的定义,表的每一行的内容,索引,都是存在 文件系统 上,以 文件 的方式存 在的,并完成与存储引擎的交互。当然有些存储引擎比如InnoDB ,也支持不使用文件系统直接管理裸设备,但现代文件系统的实现使得这样做没有必要了。在文件系统之下,可以使用本地磁盘,可以使用DAS、 NAS SAN 等各种存储系统。

        举例:
        比如现在有一个查询过来 ,我们的执行顺序是:
        1、首先从客户端发起对服务端的连接,建立连接。
        2、建立连接之后,需要专门分配一个线程来处理sql语句
        3、对接sql  Interface,相当于出入口
        4、5.7的mysql中会先去 查询缓存中是都之前这个sql已经查过了,如果查过了就不会往下执行了,会直接把结果返回给客户端。(但是8.0中已废除)
        5、然后会经过解析器来判断sql有没有问题,然后创建语法树
        6、解析器是分析出来你要做什么,优化器可以对sql进行逻辑上的优化, 例如能不能使用索引或者使用哪个索引,就是我们优化器来做的事情。
        7、需要调用对应存储api,体现的就是具体的存储引擎,然后去文件系统中做具体数据的查找,将数据加载到那内存中操作。
        8、将结果缓存起来。
        9、查询结果经过
sql  Interface,将数据返回。
        10、线程用完了放回线程池当中,结果返回给客户端

        
        小结:        
        MySQL架构图本节开篇所示。下面为了熟悉 SQL 执行流程方便,我们可以简化如下:

 

            简化为三层结构:
        1. 连接层:客户端和服务器端建立连接,客户端发送 SQL 至服务器端;
        2. SQL 层(服务层):对 SQL 语句进行查询处理;与数据库文件的存储方式无关;
        3. 存储引擎层:与数据库文件打交道,负责数据的存储和读取。

        二、sql执行流程

        2.1 MySQL 中的 SQL执行流程:

        

                

        MySQL的查询流程:
        1. 查询缓存 Server 如果在查询缓存中发现了这条 SQL 语句,就会直接将结果返回给客户端;如果没 有,就进入到解析器阶段。需要说明的是,因为查询缓存往往效率不高,所以在 MySQL8.0 之后就抛弃 了这个功能。
        
        大多数情况查询缓存就是个鸡肋,为什么呢?
SELECT employee_id,last_name FROM employees WHERE employee_id = 101;

        查询缓存是提前把查询结果缓存起来,这样下次不需要执行就可以直接拿到结果。需要说明的是,在MySQL 中的查询缓存,不是缓存查询计划,而是查询对应的结果。这就意味着查询匹配的 鲁棒性大大降,只有 相同的查询操作才会命中查询缓存 。两个查询请求在任何字符上的不同(例如:空格、注释、大小写),都会导致缓存不会命中。因此 MySQL 查询缓存命中率不高

        同时,如果查询请求中包含某些系统函数、用户自定义变量和函数、一些系统表,如 mysql 、information_schema、 performance_schema 数据库中的表,那这个请求就不会被缓存。以某些系统函数 举例,可能同样的函数的两次调用会产生不一样的结果,比如函数 NOW ,每次调用都会产生最新的当前时间,如果在一个查询请求中调用了这个函数,那即使查询请求的文本信息都一样,那不同时间的两次查询也应该得到不同的结果,如果在第一次查询时就缓存了,那第二次查询的时候直接使用第一次查询的结果就是错误的!

        此外,既然是缓存,那就有它 缓存失效的时候 MySQL的缓存系统会监测涉及到的每张表,只要该表的结构或者数据被修改,如对该表使用了 INSERT UPDATE DELETE TRUNCATE TABLE ALTER TABLE DROP TABLE DROP DATABASE 语句,那使用该表的所有高速缓存查询都将变为无效并从高速缓存中删除!对于 更新压力大的数据库 来说,查询缓存的命中率会非常低。

        总之,因为查询缓存往往弊大于利,查询缓存的失效非常频繁,所以一般建议在静态表中使用查询缓存,而且只有8以下的版本才有这个功能,所以自行了解即可。

        

         2. 解析器 :在解析器中对 SQL 语句进行语法分析、语义分析。
        分析器先做“ 词法分析 。你输入的是由多个字符串和空格组成的一条 SQL 语句, MySQL 需要识别出里面 的字符串分别是什么,代表什么。 MySQL 从你输入的 "select" 这个关键字识别出来,这是一个查询语句。它也要把字符串“T” 识别成 表名 T” ,把字符串 “ID” 识别成 ID”
        接着,要做 语法分析 。根据词法分析的结果,语法分析器(比如: Bison )会根据语法规则,判断你输入的这个 SQL 语句是否 满足 MySQL 语法
select department_id,job_id,avg(salary) from employees group by department_id;
         如果 SQL 语句正确,则会生成一个这样的语法树:
        
        3. 优化器 :在优化器中会确定 SQL 语句的执行路径,比如是根据 全表检索 ,还是根据 索引检索 等。
        举例:如下语句是执行两个表的 join:
select * from test1 join test2 using (ID)
where test1 .name = 'zhangwei' and test2 .name = 'mysql 高级课程 ' ;
        
方案 1 :可以先从表 test1 里面取出 name='zhangwei' 的记录的 ID 值,再根据 ID 值关联到表 test2 ,再判 断 test2 里面 name 的值是否等于 'mysql 高级课程 '
方案 2 :可以先从表 test2 里面取出 name='mysql 高级课程 ' 的记录的 ID 值,再根据 ID 值关联到 test1 , 再判断 test1 里面 name 的值是否等于 zhangwei
这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。优化 器阶段完成后,这个语句的执行方案就确定下来了,然后进入执行器阶段。
如果你还有一些疑问,比如优化器是怎么选择索引的,有没有可能选择错等。后面讲到索引我们再谈。
        在查询优化器中,可以分为 逻辑查询 优化阶段和 物理查询 优化阶段。
        
        4. 执行器
        截止到现在,还没有真正去读写真实的表,仅仅只是产出了一个执行计划。于是就进入了 执行器阶段

        在执行之前需要判断该用户是否 具备权限 。如果没有,就会返回权限错误。如果具备权限,就执行 SQL 查询并返回结果。在 MySQL8.0 以下的版本,如果设置了查询缓存,这时会将查询结果进行缓存。
         select * from test where id= 1 ;
        如果有权限,就打开表继续执行,打开表的时候,执行器就会根据表的引擎定义,调用存储引擎api对表进行的读写,存储引擎api只是抽象接口,下面还有个存储引擎层,具体实现还是要看表选择的存储引擎。       
     
   比如:表 test 中, ID 字段没有索引,那么执行器的执行流程是这样的:
调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 1 ,如果不是则跳过,如果是则将这行存在结果集中; 调用引擎接口取“ 下一行 ,重复相同的判断逻辑,直到取到这个表的最后一行。
执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。
        至此,这个语句就执行完成了。对于有索引的表,执行的逻辑也差不多。
        SQL 语句在 MySQL 中的流程是: SQL 语句→查询缓存→解析器→优化器→执行器

 

        2.2 MySQL8中SQL执行原理

        1. 确认profiling 是否开启

        了解查询语句底层执行的过程:select @@profiling; 或者 show variables like 'profiling';  查看是否开启计划。开启它可以让mysql ,收集在sql执行是所使用的资源情况,命令如下:

mysql> select @@profiling ;
mysql> show variables like 'profiling' ;

        

         

        profiling=0 代表关闭,我们需要把 profiling 打开,即设置为 1 :开启之后会记录sql执行过程中各个环节。
   mysql> set profiling= 1 ;
        
        2. 多次执行相同 SQL 查询
        然后我们执行一个 SQL 查询(你可以执行任何一个 SQL 查询):
        mysql> select * from employees;
         3. 查看 profiles
         查看当前会话所产生的所有 profiles
        mysql> show profiles ; # 显示最近的几次查询
        
        
        4. 查看 profile
        显示执行计划,查看程序的执行步骤:
         mysql> show profile ;

         

         当然你也可以查询指定的 Query ID,比如:

         mysql> show profile for query 7;

        查询 SQL 的执行时间结果和上面是一样的。
        上面可以证明,mysql8当中不管是否开启缓存,查询顺序都是一样的,所以缓存并没用生效。
        
        
       2.3 MySQL5.7中 SQL 执行原理 
        上述操作在MySQL5.7 中测试,发现前后两次相同的 sql 语句,执行的查询过程仍然是相同的。不是会使用 缓存吗?这里我们需要 显式开启查询缓存模式 。在 MySQL5.7 中如下设置:
        
                
        1. 配置文件中开启查询缓存
        在 /etc/my.cnf 中新增一行:
        query_cache_type = 1
         2. 重启 mysql 服务
        systemctl restart mysqld
         3. 开启查询执行计划
        由于重启过服务,需要重新执行如下指令,开启profiling
        mysql> set profiling= 1 ;
         4. 执行语句两次:
        mysql> select * from locations;
        mysql> select * from locations;
        5. 查看 profiles

        6. 查看profile

        显示执行计划,查看程序的执行步骤:
        mysql> show profile for query 1 ;

        

        mysql> show profile for query 2;

 

        结论不言而喻。执行编号2时,比执行编号1时少了很多信息,从截图中可以看出查询语句直接从缓存中获取数据。

        2.4 查询其他的性能

        此外,还可以查询更丰富的内容:
   mysql> show profile cpu,block io for query 6 ;

        

        查询cpu的相关开销和io的相关开销。

        继续:

mysql> show profile cpu,block io for query 7 ;

 

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

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

相关文章

30天学会QT---------------大项目之在线考试系统

前段时间真的很忙很忙,忙完这段时间,总算是有空来写文章了,开始写的时候我就以为能够有时间准备和写这个,但是发现有时候忙着忙着就忘记了,没有办法来写项目,真的是非常尴尬。 现在有时间了,就有充分的时间来写了。 为了避免笔记断更,我决定先存稿来写。 1、如何规划项…

打造完美Mac多屏视界,BetterDisplay Pro一键掌控!

BetterDisplay Pro for Mac是一款专为Mac用户打造的显示器管理与优化软件,旨在为用户带来卓越的视觉体验和工作效率。它凭借强大的功能和简洁易用的界面,成为了Mac用户优化显示器设置的得力助手。 一、全方位管理与优化 BetterDisplay Pro for Mac支持…

【python】OpenCV—Segmentation

文章目录 cv2.kmeans牛刀小试 cv2.kmeans cv2.kmeans 是 OpenCV 库中用于执行 K-Means 聚类算法的函数。以下是根据参考文章整理的 cv2.kmeans 函数的中文文档: 一、函数功能 cv2.kmeans 用于执行 K-Means 聚类算法,将一组数据点划分到 K 个簇中&…

DGit介绍

参考地址:http://githubengineering.com/introducing-dgit/ DGit是“Distributed Git”的简写,即分布式Git。 众所周知,Git本身就是分布式的,任何的Git仓库备份都是包含该项目所有历史版本的所有的文件,分支&#xff…

SOLIDWORKS 2024正版软件:新增功能介绍

随着科技的飞速发展,计算机辅助设计(CAD)软件在工业设计领域扮演着越来越重要的角色。SOLIDWORKS作为3D CAD软件提供商,其每一次版本更新都带来了一系列创新功能和改进,旨在为用户提供更有效、更智能、更协同的设计体验…

雨量监测预警系统:非接触式测量防汛预警

TH-SW2雨量监测预警系统是一种用于监测降雨量的重要工具,对于防汛预警工作具有重要意义。该系统采用非接触式测量技术,可以实时监测雨量数据,并自动预警,以便及时采取防汛措施,确保人民生命财产安全。 系统组成 1. 雨…

嵌入式实训day6

1、 from machine import Pin from neopixel import NeoPixel import timeif __name__"__main__"#创建RBG灯带控制对象,包含5个像素(5个RGB LED)rgb_led NeoPixel(Pin(4,Pin.OUT),5)#定义RGB颜色RED(255,0,0)GREEN(0,2…

Vue项目 [WDS] Disconnected解决方法

Vue项目出现这个错误:[WDS] Disconnected! 1.对项目运行本身造成什么实质性的影响 2.红色的提示摆在那里确实不太好看 解决 打开 Application->LocalStorage,在key上添加loglevel:webpack-dev-server,在Value上添加SILENT。

项目计划

1.什么是项目计划? 2.软件项目计划的作用 3.项目计划的内容 4.项目计划的主要内容 5.滚动计划方法 6.WBS方法 7.软件项目的特点 8.制定计划的要点 9.直接成本和间接成本 10.为什么说项目计划不是一个文档,而是一个持续的策划过程? 项目计划不…

C++升级软件时删除老版本软件的桌面快捷方式(附源码)

删除桌面快捷方式其实是删除桌面上的快捷方式文件,那我们如何去删除桌面快捷方式文件呢?软件可能已经发布过多个版本,其中的一些版本的快捷方式文件名称可能做了多次改动,程序中不可能记录每个版本的快捷方式名称,没法直接去删除快捷方式文件。本文就给出一种有效的处理办…

01:HAL库DMA解算舵机

一:实现效果 DMA解算舵机 从下到上分别为舵机1,2,3,分别由函数Servo_SetAngle1(),Servo_SetAngle2(),Servo_SetAngle3()控制。 舵机1…

anaconda的基础用法

python和包以及anaconda的概念关系 环境 “好比一栋楼,在楼里面分配一间屋给各种‘包’放,每间房里面的‘包’互不影响” 激活环境 “告诉电脑,我现在要用这个屋子里面的‘包’来做东西了所以要进这间屋子” 移除环境 “现在这个屋子里…

基于Java的冬奥会科普平台

开头语:你好,我是计算机学姐码农小野。如果你对冬奥会科普平台感兴趣或有其他技术需求,欢迎随时私信我。 开发语言:Java 数据库:MySQL 技术:Java、B/S架构 工具:MyEclipse、MySQL 系统展示…

最值得入手的宠物空气净化器!希喂、352、安德迈真实测评~

随着天气越来越热,猫咪们也都开始掉毛啦。这时候,家里面到处都飘浮着猫咪们的浮毛和粑粑异味。抵抗力较差的铲屎官,身体就会出现一些问题,例如打喷嚏、咳嗽等呼吸道问题。 很多铲屎官以为用粘毛器、吸尘器等工具就能将猫咪们掉落…

欢乐钓鱼大师游戏攻略:萌新必备攻略大全!钓鱼脚本!

《欢乐钓鱼大师》是一款休闲益智类游戏,以钓鱼为主题,玩家需要通过各种钓鱼任务和挑战,收集不同种类的鱼类,并提升自己的钓鱼技术和装备。本文将为大家详细解析游戏的各个方面,帮助玩家更好地掌握游戏技巧,…

PAT B1008. 数组元素循环右移问题

题目描述 一个数组A中存有N(N>O)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M≥0)个位置,即将A中的数据由( …)变换为(……)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,则应如何设计移动的方法?输…

FastAdmin后台开发框架 lang 任意文件读取漏洞复现

0x01 产品简介 FastAdmin是一款基于PHPBootstrap的开源后台框架,专为开发者精心打造。它基于ThinkPHP和Bootstrap两大主流技术构建,拥有完善的权限管理系统和一键生成CRUD等强大功能。FastAdmin致力于提高开发效率,降低开发成本,…

第二证券炒股知识:新手炒股要注意什么风险?

股票商场作为现代金融商场的重要组成部分,招引了众多出资者的目光。但是关于新手来说炒股赚钱并不是那么简单的,其间蕴含着诸多危险。关于新手炒股要注意什么危险,中航资本下面就为大家具体介绍一下。 新手炒股要注意的危险: 1、…

云计算【第一阶段(16)】安装及管理程序

一、linux 应用程序基础 当我们主机安装linux操作系统 时候,也会同时安装一些软件或网络服务等等,但是随着系统一起安装的软件包毕竟他是少数的, 能够实现的功能也是有限的,那么我们相拥为主机提供更多更丰富的功能的时候&#x…

OpenAI 600万天价年薪震惊网友,全美顶尖AI公司薪酬大曝光!

最近,一张美国科技大厂的薪酬表曝出,OpenAI以500万起薪领衔。初创公司给出的薪酬,竟然超过了所有大型科技公司。不过初级码农,时薪却低至85元。 顶级公司的AI工程师能挣多少钱? 最近,这张美国科技大公司的…