这篇文章带你了解sql语句是怎么执行的

2023-11-09


在这里插入图片描述

mysql有各种版本的架构图,但基本上都可以分为Server层和存储引擎层

一、mysql架构分析

下面是mysql的一个简要架构图:

在这里插入图片描述
Server层:主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块 binglog日志模块。
存储引擎: 主要负责数据的存储和读取,采用可以替换的插件式架构,支持InnoDB、MyISAM、Memory等多个存储引擎,其中InnoDB引擎有自有的日志模块redolog 模块。
InnoDB 5.5.5版本作为默认引擎。

  • 连接器
    主要负责用户登录数据库,进行用户的身份认证,包括校验账户密码,权限等操作,如果用户账户密码已通过,连接器会到权限表中查询该用户的所有权限,之后在这个连接里的权限逻辑判断都是会依赖此时读取到的权限数据,也就是说,后续只要这个连接不断开,即时管理员修改了该用户的权限,该用户也是不受影响的。
  • 查询缓存
    连接建立后,执行查询语句的时候,会先查询缓存,Mysql会先校验这个sql是否执行过,以Key-Value的形式缓存在内存中,Key是查询预计,Value是结果集。如果缓存key被命中,就会直接返回给客户端,如果没有命中,就会执行后续的操作,完成后也会把结果缓存起来,方便下一次调用当然在真正执行缓存查询的时候还是会校验用户的权限,是否有该表的查询条件。
    Mysql 查询不建议使用缓存,因为对于经常更新的数据来说,缓存的有效时间太短了,往往带来的效果并不好,对于不经常更新的数据来说,使用缓存还是可以的,Mysql 8.0 版本后删除了缓存的功能,官方也是认为该功能在实际的应用场景比较少,所以干脆直接删掉了。
  • 分析器
    mysql 没有命中缓存,那么就会进入分析器,分析器主要是用来分析SQL语句是来干嘛的,分析器也会分为几步:
    第一步,词法分析,一条SQL语句有多个字符串组成,首先要提取关键字,比如select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。
    第二步,语法分析,主要就是判断你输入的sql是否正确,是否符合mysql的语法。
    完成这2步之后,mysql就准备开始执行了,但是如何执行,怎么执行是最好的结果呢?这个时候就需要优化器上场了。
  • 优化器
    优化器的作用就是它认为的最优的执行方案去执行(虽然有时候也不是最优),比如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等。
  • 执行器
    当选择了执行方案后,mysql就准备开始执行了,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果

二、语句分析

2.1 查询语句

说了以上这么多,那么究竟一条sql语句是如何执行的呢?其实我们的sql可以分为2种,一种是查询,一种是更新(增加,更新,删除)。我们先分析下查询语句,语句如下:

select * from tb_student  A where A.age='18' and A.name='张三';
  1. 结合上面的说明,我们分析下这个语句的执行流程:
    先检查该语句是否有权限,如果没有权限,直接返回错误信息,如果有权限,在mysql8.0版本以前,会先查询缓存,以这条sql语句为key在内存中查询是否有结果,如果有直接缓存,如果没有,执行下一步。

  2. 通过分析器进行词法分析,提取sql语句的关键元素,比如提取上面这个语句是查询select,提取需要查询的表名为tb_student,需要查询所有的列,查询条件是这个表的id=‘1’。然后判断这个sql语句是否有语法错误,比如关键词是否正确等等,如果检查没问题就执行下一步。

  3. 接下来就是优化器进行确定执行方案,上面的sql语句,可以有两种执行方案:

  a.先查询学生表中姓名为“张三”的学生,然后判断是否年龄是18。
  b.先找出学生中年龄18岁的学生,然后再查询姓名为“张三”的学生。

. 那么优化器根据自己的优化算法进行选择执行效率最好的一个方案(优化器认为,有时候不一定最好)。那么确认了执行计划后就准备开始执行了。

  1. 进行权限校验,如果没有权限就会返回错误信息,如果有权限就会调用数据库引擎接口,返回引擎的执行结果。

2.2 更新语句

以上就是一条查询sql的执行流程,那么接下来我们看看一条更新语句如何执行的呢?sql语句如下:

update tb_student A set A.age='19' where A.name='张三';

我们来给张三修改下年龄,在实际数据库肯定不会设置年龄这个字段的,不然要被技术负责人打的。其实条语句也基本上会沿着上一个查询的流程走,只不过执行更新的时候肯定要记录日志啦,这就会引入日志模块了,mysql 自带的日志模块式binlog(归档日志),所有的存储引擎都可以使用,我们常用的InnoDB引擎还自带了一个日志模块redo log,我们就以InnoDB模式下来探讨这个语句的执行流程。流程如下:

  1. 先查询到张三这一条数据,如果有缓存,也是会用到缓存。
  2. 然后拿到查询的语句,把 age 改为19,然后调用引擎API接口,写入这一行数据,InnoDB引擎把数据保存在内存中,同时记录redo log,此时redo log进入prepare状态,然后告诉执行器,执行完成了,随时可以提交。
  3. 执行器收到通知后记录binlog,然后调用引擎接口,提交redo log 为提交状态。
  4. 更新完成。

问题

为什么要用两个日志模块,用一个日志模块不行吗?

  • 这就是之前mysql的模式了,MyISAM引擎是没有redo log的,那么我们知道它是不支持事务的,所以并不是说只用一个日志模块不可以,只是InnoDB引擎就是通过redo log来支持事务的。

用两个日志模块,但是不要这么复杂行不行,为什么redo log 要引入prepare预提交状态?这里我们用反证法来说明下为什么要这么做?

  • 先写redo log 直接提交,然后写 binlog,假设写完redo log 后,机器挂了,binlog日志没有被写入,那么机器重启后,这台机器会通过redo log恢复数据,但是这个时候bingog并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。

  • 先写binlog,然后写redo log,假设写完了binlog,机器异常重启了,由于没有redo log,本机是无法恢复这一条记录的,但是binlog又有记录,那么和上面同样的道理,就会产生数据不一致的情况。

  • 如果采用redo log 两阶段提交的方式就不一样了,写完binglog后,然后再提交redo log就会防止出现上述的问题,从而保证了数据的一致性。

有没有一个极端的情况呢?假设redo log 处于预提交状态,binglog也已经写完了,这个时候发生了异常重启会怎么样呢?

  • 判断redo log 是否完整,如果判断是完整的,就立即提交。
  • 如果redo log 只是预提交但不是commit状态,这个时候就会去判断binlog是否完整,如果完整就提交 redo log, 不完整就回滚事务。
  • 这样就解决了数据一致性的问题。

三. 总结

  • Mysql 主要分为Server曾和引擎层,Server层主要包括连接器、查询缓存、分析器、优化器、执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用。
  • 引擎层是插件式的,目前主要包括,MyISAM,InnoDB,Memory等。
  • sql等执行过程分为两类,一类对于查询等过程如下:权限校验—》查询缓存—》分析器—》优化器—》权限校验—》执行器—》引擎
  • 对于更新等语句执行流程如下:分析器----》权限校验----》执行器—》引擎—redo log prepare—》binlog—》redo log commit

END!!! 如果这篇文章对你有用的话,不胜感激!!!
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这篇文章带你了解sql语句是怎么执行的 的相关文章

随机推荐

  • 听说现在流行卷应用?开发者们都开始调用文心API开发了?!

    随着大模型的涌现 我们喜悦于其远远超越小模型的性能 但又不得不面临大模型开发难的困境 训练难 微调难 部署难 开发者难以将其投入实际生产 不仅面临资源的限制 更面临高精数据难寻 时间成本过高等问题 为了让平台更多开发者可以进行大模型开发 体
  • vue import..from..说明

    import Vue from vue import axios from axios import App from App import store from store import router from router import
  • Java中IO流——详解字节流之FileOutputStream和FileInputStream

    文章目录 前言 一 Java流的概述 二 常用字节流分类 1 字节输出输入流 1 FileOutputStream 2 FileInputStream 3 复制小练习 4 异常捕获 总结 前言 我们之前学习了Java中的异常机制和File类
  • 【区块链】Python开发EOS机器人与WAX链游脚本常用工具

    前言 众所周知 开发EOS机器人与WAX链游脚本 我们都需要调用eosio chain api https developers eos io manuals eos latest nodeos plugins chain api plug
  • mybatis多表联查sql用法示例

    用到sql变量 sql复用
  • ssm打印sql如何开启_ssm环境下配置log4j打印mybatis的sql语句

    首先附上官网的说明文档 mybatis Logging 环境spring4 3 0 springmvc4 3 0 mybatis3 4 0 按官方文档的说明 1 SLF4J 2 Apache Commons Logging 3 Log4j
  • 使用invoke方法解决跨线程访问的问题

    C 中禁止跨线程直接访问控件 InvokeRequired是为了解决这个问题而产生的 当一个控件的InvokeRequired属性值为真时 说明有一个创建它以外的线程想访问它 获取一个值 该值指示调用方在对控件进行方法调用时是否必须调用 I
  • js+bootstrap+jquery+vue实现房贷计算器

    代码链接 loan 使用vue js html css实现房贷的计算 版权声明 本文为CSDN博主 小样还想跑 的原创文章 遵循CC 4 0 BY SA版权协议 转载请附上原文出处链接及本声明
  • 23 种设计模式详解(全23种)

    设计模式的分类 总体来说设计模式分为三大类 创建型模式 共五种 工厂方法模式 抽象工厂模式 单例模式 建造者模式 原型模式 结构型模式 共七种 适配器模式 装饰器模式 代理模式 外观模式 桥接模式 组合模式 享元模式 行为型模式 共十一种
  • 人手一份核武器:Android手机装Kali Linux

    首先这是安卓手机的专属工具 因为Android基于Linux 所以就有了得天独厚的优势 1 先下载好Linux Deploy 前提是本手机已root 2 按下图配置 不过有地方需要说明 Distribute Suite已经改为sana 但无
  • Windows Server 2012 R2 设置 smtp 服务器

    Windows Server 2012 2012 R2 安装和配置 SMTP 服务器 安装 SMTP 服务器 以下是安装 SMTP 服务器功能的步骤 打开 服务器管理器 单击键盘上的 Windows 按钮 输入 服务器管理器 在 结果 窗口
  • FW-1设备配置命令

    DCFW 1800 config hostname FW 1 FW 1 config ip vrouter trust vr FW 1 config vrouter ip route 0 0 0 0 0 202 11 33 26 FW 1
  • cmd创建用户并初始化新用户桌面

    author skate time 2013 12 20 功能 在win2003上创建用户 并初始化新用户的桌面 echo InternetShortcut gt gt MysqlTool url echo URL C Program Fi
  • Qt之pro配置多个子工程/子模块

    简述 进行Qt项目开发的时候 尤其是大型项目 经常涉及多工程 多模块问题 其主要思想还是模块化 目的是为了降低程序复杂度 使程序设计 调试和维护等操作简单化 简述 配置 效果 多工程 多模块 更多参考 配置 效果 多工程 如果需要管理多工程
  • JavaMap集合&Stream流

    1 Map集合 1 1Map集合概述和特点 Map集合概述 interface Map
  • Python-Thread(通俗易懂)

    此类表示在单独的控制线程中运行的活动 有两种方法可以指定该活动 一是将可调用对象传递给构造函数 二是通过覆盖子类中的run 方法 如果你对线程不太理解 我们可以打个比方 把线程数看作车辆数 我们来完成一个简单的客运运输工作 以下为了方便理解
  • 第8届Python编程挑战赛初赛真题剖析-2022年全国青少年信息素养大赛

    导读 超平老师计划推出 全国青少年信息素养大赛Python编程真题解析 50讲 这是超平老师解读Python编程挑战赛系列的第1讲 全国青少年信息素养大赛 原全国青少年电子信息智能创新大赛 是 世界机器人大会青少年机器人设计与信息素养大赛
  • VC++ MapWinGis篇(二)

    添加高德图层 ArcGisProvider h pragma once include BaseProvider h class ArcGisBaseProvider public BaseProvider public ArcGisBas
  • Java RMI 远程代码执行漏洞

    0x01 漏洞描述 Java RMI 远程代码执行漏洞 Java RMI服务是远程方法调用 是J2SE的一部分 能够让程序员开发出基于JAVA的分布式应用 一个RMI对象是一个远程Java对象 可以从另一个Java虚拟机上 甚至跨过网络 调
  • 这篇文章带你了解sql语句是怎么执行的

    一条sql语句是怎么执行的 一 mysql架构分析 二 语句分析 2 1 查询语句 2 2 更新语句 三 总结 mysql有各种版本的架构图 但基本上都可以分为Server层和存储引擎层 一 mysql架构分析 下面是mysql的一个简要架