首页 > 数据库 >MySQL的sql语句执行流程(简述)

MySQL的sql语句执行流程(简述)

时间:2023-05-27 16:34:24浏览次数:55  
标签:服务器端 sql 查询 简述 SQL MySQL 执行

导言:

MySQL和服务器端对接的时候,我们知道一般就是服务器端会打包一些SQL命令去增删改查数据库,这个打包的数据库SQL语句数据包一般为4MB,再大一些就不会被数据库端接收了

但是我们可以自己更改默认大小,当数据包到达数据库端以后,它们会经历那些操作然后返回结果给服务器端呢?

大概有:查询缓存,SQL解析,预处理器,SQL优化器,执行器,存储引擎,返回结果给服务器端

 上面就是sql命令的整体执行流程,接下来我们对各个步骤进行拆分,细化的讲解一下他们都做了些什么操作

一.连接

在服务器端和数据库端的连接方式中,我们采用的是半双工的方式,也就是说要么是一次申请到达数据库端,要么是一次结果响应到服务器端

不存在一个数据包还没全部到数据库端,它的结果已经开始响应到服务器的情况

另外,作为第三方连接,我们一般都是使用的数据库连接池,数据库端一般会提供很多的连接接口,供服务器端不同的用户去连接,使用完了然后释放

既然作为第三方连接,它就会使用到数据库驱动,就像JDBC,C3P0等等

此外,数据库一次接收服务器端发来的数据包大概有4MB,多了它就选择不接受了,当然我们也可以自己更改默认接收包的大小

在数据查询完了,返回结果给服务器端也是,它只能一次全部接收,不能只接受一部分结果响应

二.查询缓存

MySQL的缓存是一个很鸡肋的东西,它很少用,但是要想了解底层就必须知道它,它的存在很鸡肋,也导致使用它的很少

数据缓存指的是对已经查询过的数据放在缓存中,下次sql命令来了以后先查询缓存中有没有已经查过的,没有才会去执行新的一次查询,有则直接返回给服务器端

缓存的构成是Map集合,他有两个属性组成,key和value ,key用来存放sql语句,而value用来存放查询的结果

看起来使用缓存会提升查询的效率,但是真正到实战开发以后就会知道,它并没有那么好用,首先一般我们的查询语句都是不同的,很难连续两次的sql完全一样,最好的情况也是条件相差不大

但是也是达不到完全吻合key值的sql,所以实战开发使用效率十分低,伴随着的就是它的缺点,因为它是sql执行的第一个操作,每个sql进来的都要去找一遍,但是都是找不到的

白白的浪费了这么多的开销,而且每一次对数据库的增删改都会影响这个缓存,使其失效,维护又是很大的开销

所以在MySQL 5.7版本是默认关闭这个缓存的,他会跳过查询缓存这一步直接sql解析,到了MySQL8.0的时候直接把查询缓存删掉了,不再需要这个功能了

三.SQL解析

sql解析执行包括了:词法分析,语法分析,分析机,生成语法树

 词法分析:从左到右一个字符、一个字符地输入,然后根据构词规则识别单词。将会生成Token词

在进行了词法分析以后,他会把sql默认扫描成两个部分,一个是关键字(select,insert,from,where,group by .......)一个是非关键字(查询的字段,查询的表,查询的筛选条件,分组条件)

语法分析,分析机:它们两个是一起工作的,它们对词法分析生成的Token词开始循环构造语法树,直到整个SQL语句扫描完成了,就构成了一棵语法树

值得注意的是,当MySQL中我们的关键字写错了以后会在词法分析阶段报错,当我们没有加上表名,或条件等格式错误了会在语法分析阶段报错

生成语法树:由每次分析机的输出构成

 从上面的语法上树不难看出原sql语句,这就是sql分析阶段,当这一步完成以后,就会进入预处理阶段

四.预处理器

根据一些mysql规则进一步检查解析树是否合法。如检查查询的表名、列名是否正确,是否有表的权限

这一步操作目的是解决原来每一句sql都会单独解析执行的问题,后来变成了使用预处理器,对于相同的命令模板,不断的替换参数,减少对表权限和语法树是否合法的计算

生成命令模板:对于第一次进入的sql语句肯定是没有命令模板的,所以它需要参与生成命令模板 ,比如select  id  from student  where id =1; 那么 “ select  id  from student  where id = ” 就会成为模板

当模板生成了以后,对于student这个表,属性为id的字段,这个模板是已经检查过有没有权限的了,它在这个模板上都是有记录的

替换参数条件:这是对于有模板的情况下,我们就会直接使用参数替换的形式,把命令完成,比如这个时候有一条sql:select  id  from student  where id = 100 ;很显然,上次我们已经生成过模板了,

就可以直接用,模板就是select  id  from student  where id = 这个时候就只需要把参数替换掉,这次 id = 100;就把原来的 1 替换为100 ,这样做的好处就是,不用再去检查语法树合不合法了,

不用去看表是否有没有权限了,因为在生成模板的时候这些操作都是做过的了,如果模板语法树不合法,拿这次的sql也不合法,如果模板没有student表的权限,那么这次也没有

极大避免了二次计算和操作,对性能的提升非常大

 经过了预处理器以后,就拿到了这句sql是否有执行的权力,即能否更改表和查询表的权力,

如果权限没有问题,那么就可以进行下一步:SQL优化

五.SQL优化器

当语法树被认为是合法的了,并且由优化器将其转化成执行计划。一条查询可以有很多种执行方式,最后都返回相同的结果。优化器的作用就是找到这其中最好的执行计划。

执行计划:mysql不会生成查询字节码来执行查询,mysql生成查询的一棵指令树,然后通过存储引擎执行完成这棵指令树并返回结果。最终的执行计划包含了重构查询的全部信息。

 查询的生命周期的下一步是将一个SQL转换成一个执行计划,mysql在依照这个执行计划和存储引擎进行交互。这包含多个子阶段:解析SQL、预处理、优化SQL执行计划。这个过程中任何错误都可能终止查询。

  • 查询优化器:当语法树被认为是合法的了,并且由优化器将其转化成执行计划。一条查询可以有很多种执行方式,最后都返回相同的结果。优化器的作用就是找到这其中最好的执行计划。
  • 执行计划:mysql不会生成查询字节码来执行查询,mysql生成查询的一棵指令树,然后通过存储引擎执行完成这棵指令树并返回结果。最终的执行计划包含了重构查询的全部信息。

在优化器的内部,是开发者定义的许多“优化规则”来进行优化的,如关联查询重排,索引优选,连接查询重组,优化排序,优化聚合函数,提前终止查询,等价变化等;

这里我们简单来列举一下索引优选:

 这个简单的例子应该可以感受到SQL优化器的作用是干什么的了,它内置很多规则,它贴合物理层,有自己的执行规则,同时又因为一些不合格的程序员写的sql不合规

这就导致SQL优化器非常重要了,能到sql优化器处理的sql基本上语法都是没问题的,主要的是怎么提高sql的执行效率,这就是优化器最大的作用

只要SQL优化器处理完了以后,就会生成执行计划,这个执行计划就是存储引擎的处理单元

生成执行计划以后,他就会交给执行器,去调用存储存储引擎的相应Headler API来完成相应的执行计划

六.执行器

这里的执行器和操作系统的操作系统差不多,都是负责调用和分发的,在sql执行中,执行器扮演两个角色

  • 调用存储引擎的Headler API 处理执行计划
  • 接收存储引擎返回的结果,并将它返回给服务器端

七.存储引擎(InnoDB)

我们常说的索引查询,遍历查询,临时表查询等等行为都是在存储引擎中完成的

 

 在我前面写的MySQL之存储引擎中有写道InnoDB是如何存储数据的,主要是内存的读写速度比硬盘的快,所以有了Buffer Pool ,这里当一个查询计划来了以后,他首先会去Buffer Pool中查看是否有关这次查询的相关更新,

如果没有,我们就会直接去磁盘中刷出数据到Buffer Pool中,然后由存储引擎负责返回给MySQL执行器,最后返回给服务器端

当Buffer Pool中有关此次查询的更新时,我们需要等到存储引擎把旧的值放到undo  Log(用于事务回滚的日志)中,然后就会更新Buffer Pool和把更新数据刷入到磁盘,此时就可以去根据查询条件,查询数据到Buffer Pool中,

然后返回给MySQL执行器

有关InnoDB的存储,可以去看看我以前写的博客MySQL存储之InnoDB

拓展:什么是MySQL的二阶段提交?

MySQL的二阶段提交指的是MySQL为了保证redo  Log和 Binlog的一致性而产生的一种设计,把日志写入和日志提交拆分成两个阶段,保证数据写入的一致性

redo  log是事务日志,Binlog是数据变更的逻辑日志,二者必须同时成功,保证记录一致,

二阶段提交指的就是:

第一阶段:在事务开始时,MySQL会把操作记录到redo  log中,同时会在redo  log中打上 prepare 的标志,表示在redo log中事务开始了

第二阶段:在事务完成以后,会先记录到BinLog中,然后再去redo log中标记上commit,这样就保证了redo log 和binLog的一致性

以上就是MySQL的二次提交,所以InnoDB在写入redo log并不是一次写完的,而是分成两个阶段 prepare 和 commit

对应情况:

在写入 redo  log 时崩溃:两个日志中都没有数据,满足数据的一致性

在写入redo log的prepare时崩溃:由于没有打上commit 的标记,所以在Binlog中找不到对应的这个事务的id,那么就需要执行回滚操作

在写入Binlog之后崩溃:由于redo log中的事务id可以在Bin log 中可以找到(表示事务已经刷入磁盘),所以可以直接提交数据,为redo log中事务打上commit标记

 

标签:服务器端,sql,查询,简述,SQL,MySQL,执行
From: https://www.cnblogs.com/5ran2yl/p/17436524.html

相关文章

  • SQL(Structured Query Language)介绍及查询示例
    SQL(StructuredQueryLanguage)是结构化查询语言的缩写,它是一种专门用于操作关系型数据库的编程语言。SQL可以用于数据的存储、查询、更新、删除等常见操作,并且是目前世界上最流行的关系型数据库操作语言。SQL的主要特点包括:1.简单易学:SQL的语法清晰简单,易于学习和使用。2.......
  • HANA SQL:ALTER USER
    ALTERUSER语法:ALTERUSER<USER_NAME><ALTER_USER_OPTION>描述:ALTERUSER语句用于修改数据库用户。<USER_NAME>必须制定一个现有的数据库用户。每个用户可以为自己执行ALTERUSER。但并非所有<ALTER_USER_OPTION>可以由用户自己制定。对于<ALTER_USER_OPTION>其他用户,只有拥......
  • 在 Kubernetes 上部署 RadonDB MySQL 集群
    1.mysql部署部署参考文档:https://radondb.com/docs/mysql/v2.2.0/installation/on_kubernetes/#content参数:https://github.com/radondb/radondb-mysql-kubernetes/blob/main/docs/zh-cn/config_para.md官网:https://radondb.comhelmrepoaddradondbhttps://radondb.github.......
  • 一个mysql的group_concat导致的问题
    好久都没有写点东西了,是时候有点写东西的必要了。去年下年底离职了,躺了几个月,最近又兜兜转转换了一家公司继续当牛马了,前段时间八股文背了好多,难受呀,不过我也趁着前段时间自己也整理了属于我自己的八股文,有好几万字吧,哈哈哈,以后就不用到处去找八股文了。说回正题,这......
  • Mysql练习
    1. 练习11.1 选择题   811代码在E:\java学习\初级\course166\db_exercise01--选择题写法对错判断811--错误,as可以省略但是AnnualSalary中间有空格会被认为Salary是最终的别名SELECTename,sal*12ASAnnualSalaryFROMempSELECTename,sal*12AS"AnnualSalary"FR......
  • MySQL学习进阶篇Day2
    2.索引2.1索引概述2.1.1介绍索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。 一提到数据结构,大......
  • MySQL数据类型
    数据类型的选取原则:更小的通常更好:尽量使用可以正确存储数据的最小数据类型(它们占用更少的磁盘,内存,cpu缓存,处理时需要的cpu周期也更少)简单:简单数据类型的操作通常所需cpu周期更少,例如整型就是比字符串类型的操作代价更低尽量避免NULL:最好指定列为NOTNULL,如果......
  • ubuntu 20.4 安装msyql+创建mysql用户
    sudoapt-getupdatesudoapt-getupgratesudoaptinstallmysql-server设置运行远程访问修改:sudovim/etc/mysql/mysql.conf.d/mysqld.cnf用#注释掉bind-address=127.0.0.1进入mysql创建用户mysql-uroot-pCREATEUSER'test'@'%'IDENTIFIEDBY'12345......
  • 解析SQL语句
    为鉴权/血缘解析SQL语句背景:公司的数仓是集中式数仓,大部分业务公用hive环境,少部分业务通过数仓透出的文件进行数据交换。问题:所有业务都可以访问所有的hive表,急需要权限管控。那解析各个业务提交的SQL文件就成了首要任务。解决方案1.Jsqlparser是一个java的jar包,可以解析简......
  • WPF入门实例 WPF完整例子 WPF DEMO WPF学习完整例子 WPF实战例子 WPF sql实例应用 WPF
    WPF和WinForms都是用于创建Windows桌面应用程序的开发框架,它们有一些相似之处,但也有很多不同之处。在开发速度方面,这取决于具体情况。如果您熟悉WinForms开发并且正在开发简单的界面应用程序,则可能会比使用WPF更快速地完成任务。然而,在设计和实现复杂的用户界面时,WPF可......