SQL执行原理

MyBatis动态 SQL 的执行原理 MyBatis 的动态 SQL 提供了强大的功能,使得开发者能够灵活地生成复杂的 SQL 查询。通过使用。 阅读详情

SELECT 语句执行原理

连接器

当我们通过客户端访问MySQL服务器前,要做的第一步就是需要先经过TCP三次握手,因为 MySQL 是基于TCP协议进行传输的。TCP 网络连接建立成功后,服务端与客户端之间会建立一个session会话,紧接着会对登录的用户名和密码进行效验,首先会查询自身的用户表信息,判断输入的用户名是否存在,如果存在则会判断输入的密码是否正确。密码正确后,会从连接池中分配一条空闲线程维护当前客户端的连接,如果没有空闲线程,则会创建一条新的工作线程。之后线程会查询用户所拥有的权限,并对其授权,后续SQL执行时,都会先判断是否具备相应的权限。

空闲连接在超过最大空闲时长(wait_timeout)之后,连接器会自动将它断开。

一个处于空闲状态的连接被服务端主动断开后,客户端并不会马上知道,等到客户端在发起下一个请求的时候,才会收到报错。
在这里插入图片描述

连接池

Connection Pool是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请→使用→释放。主要是为了复用线程、管理线程以及限制最大连接数。

当一个客户端尝试与 MySQL建立连接时,MySQL内部都会派发一条线程负责处理该客户端接下来的所有工作。线程的频繁创建和销毁都会耗费大量资源,通过复用线程的方式,不仅能减少开销,还能避免内存溢出等问题。

数据库Connection Pool可以设置最小连接数和最大连接数:

  • 最小连接数:是连接池一直保持的数据库连接,如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费
  • 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中

查询缓存

如果是查询(select)语句MySQL 就会先去查询缓存( Query Cache )里查找缓存数据,看看之前有没有执行过这一条命令,这个查询缓存是以 key-value 形式保存在内存中的,key 为 SQL 查询语句的哈希值,value 为 SQL 语句查询的结果。如果命中查询缓存,那么就会直接返回value给客户端。如果没有命中查询缓存,那么就要往下继续执行,等执行完后,查询的结果就会被存入查询缓存中。查询缓存往往弊大于利,因为只要有对表的更新,就会导致表上的所有查询缓存被清空。所以,MySQL8.0 版本直接将查询缓存删掉了。

💡 这里说的查询缓存是server层的,也就是MySQL8.0版本移除的是server层的查询缓存,并不是Innodb存储引擎中的Buffer Pool。

解析 SQL

在正式执行SQL查询语句之前,MySQL会先对SQL语句进行解析,这个工作交由解析器来完成。解析器可以将输入的 SQL 语句转换为计算机可以理解的形式(语法树,Syntax Tree)。

解析器会做以下两件事情:

  • 词法分析:MySQL会根据输入的字符串识别出关键字出来,构建出SQL语法树
  • 语法分析:根据词法分析的结果,语法分析器会根据语法规则,判断输入的SQL语句是否满足语法规则

语法树大致结构如下:
在这里插入图片描述

💡 当词法分析和语法分析出错时,分析器会抛出异常。比如语法结构出错、出现了无法识别的字符等。表或字段不存在并不是在分析器里做的,而是在预处理阶段完成。

执行 SQL

每条 SQL 语句主要可以分为以下这三个阶段:

  1. prepare预处理阶段:检查 SQL 查询语句中的表或者字段是否存在;将select*中的*符号,扩展为表上的所有字段
  2. optimize优化阶段:优化器会根据语法树制定多个执行计划,然后确定最优的执行计划
  • 在表里存在多个索引的时候,决定使用哪个索引;
  • 在一个语句有多表关联(join)的时候,决定各个表的连接顺序。
  1. execute执行阶段:判断用户权限,然后根据执行计划执行 SQL 语句

SELECT 查询过程

  1. 客户端通过连接器连接 MySQL 服务
  2. 连接成功后向SQL接口发送SQL语句请求
  3. SQL接口接收到SQL查询语句会先去缓存查询,如果命中返回给客户端,否则交给解析器
  4. 解析器在拿到SQL语句后会判断语法是否正确,正确会生成SQL语法树交给优化器,否则报错给客户端
  5. 优化器会根据SQL语法树生成一个最优的执行计划交给执行器执行
  6. 执行器拿到执行计划调用存储引擎来获取数据响应给客户端

UPDATE 语句执行原理

update其实包括了更新、插入和删除。看过MyBatis源码的小伙伴应该都知道Executor里面也只有doQuery()和doUpdate()方法,没有doDelete()和doInsert()。

缓冲池

首先,InnoDB的数据都是放在磁盘上的,操作数据有一个最小的逻辑单位,叫做页(索引页和数据页)。我们对于数据的操作,不是每次都直接操作磁盘,因为磁盘的速度太慢了。InnoDB设计了缓冲池,也就是把磁盘读到的页放到一块内存区域里面。这个内存区域就叫Buffer Pool。

下一次读取相同的页,先判断是不是在缓冲池里面,如果是就直接读取不用再次访问磁盘。修改数据的时候,先修改缓冲池里面的页。内存的数据页和磁盘数据不一致的时

候,我们把它叫做脏页。InnoDB里面有专门的后台线程把Buffer Pool的数据写入到磁盘,每隔一段时间就一次性地把多个修改写入磁盘,也就是刷新脏页。

Buffer Pool是InnoDB里面非常重要的一个结构,它的内部又分成几块区域。前面的篇幅我们已经介绍了InnoDB的内存结构和磁盘结构,这里我们做一下简单的回顾。

InnoDB 内存结构和磁盘结构

Buffer Pool主要分为3个部分:Buffer Pool、Change Buffer、AdaptiveHash Index,另外还有一个(redo)Log Buffer。

Buffer Pool

BufferPool缓存的是页信息,包括数据页、索引页。内存缓冲区对于提升读写性能有很大的作用。

内存的缓冲池写满了怎么办?InnoDB用LRU算法来管理缓冲池(链表实现,不是传统的 LRU,分成了Younf 和 Old),经过淘汰的数据就是热点数据。

🤔 思考一个问题:当需要更新一个数据页时,如果数据页在Buffer Pool中存在,那么就直接更新好了。否则的话就需要从磁盘加载到内存,再对内存的数据页进行操作。也就是说,如果没有命中缓冲池,至少要产生一次磁盘 IO,有没有优化的方式呢?

Change Buffer

如果这个数据页不是唯一索引,不存在数据重复的情况,也就不需要从磁盘加载索引页判断数据是不是重复(唯一性检查)。这种情况下可以先把修改记录在内存的缓冲池中,从而提升更新语句(Insert、Delete、Update)的执行速度。这一块区域就是Change Buffer。5.5 之前叫Insert Buffer插入缓冲,现在也能支持Delete和Update。我们把Change Buffer记录到数据页的操作叫做merge。

💡 那么什么时候发生merge呢?有几种情况:在访问这个数据页的时候,或者通过后台线程或者数据库关闭、Redo Log写满时触发。

如果数据库大部分索引都是非唯一索引,并且业务是写多读少,不会在写数据后立刻读取,就可以使用 ChangeBuffer(写缓冲)。写多读少的业务,调大这个值:

SHOW VARIABLES LIKE 'innodb_change_buffer_max_size';
Log Buffer

如果Buffer Pool里面的脏页还没有刷入磁盘时,数据库宕机或者重启,这些数据丢失。如果写操作写到一半,甚至可能会破坏数据文件导致数据库不可用。为了避免这个问题,InnoDB把所有对页面的修改操作专门写入一个日志文件,并且在数据库启动时从这个文件进行恢复操作(实现 crash-safe)——用它来实现事务的持久性。这个文件就是磁盘的 Redo Log(叫做重做日志),对应于ib_logfile0 和 ib_logfile1,每个 48M。

这种日志和磁盘配合的整个过程 ,其实就是 MySQL 里的 WAL 技术(Write-Ahead Logging),它的关键点就是先写日志,再写磁盘。

show variables like 'innodb_log%';

同样是写磁盘,我们为什么不直接写到db file里面去而是先写日志再写磁盘呢?

我们先来了解一下随机 I/O 和顺序 I/O 的概念:磁盘的最小组成单元是扇区,通常是 512 个字节。操作系统和磁盘打交道,读写磁盘,最小的单位是块 Block。

如果我们所需要的数据是随机分散在不同页的不同扇区中,那么找到相应的数据需要等到磁臂旋转到指定的页,然后盘片寻找到对应的扇区,才能找到我们所需要的一块数据,依

次进行此过程直到找完所有数据,这个就是随机IO,读取数据速度较慢。

假设我们已经找到了第一块数据,并且其他所需的数据就在这一块数据后边,那么就不需要重新寻址,可以依次拿到我们所需的数据,这个就叫顺序 IO。

刷盘(将内存中的数据写入磁盘)是随机 I/O,而记录日志是顺序 I/O,顺序 I/O 效率更高。因此先把修改写入日志,可以延迟刷盘时机,进而提升系统吞吐。

当然 Redo Log 也不是每一次都直接写入磁盘,在Buffer Pool里面有一块内存区域Log Buffer专门用来保存即将要写入日志文件的数据,默认16M,它一样可以节省磁盘 IO。

需要注意:Redo Log 的内容主要是用于崩溃恢复。磁盘的数据文件,数据来自Buffer Pool。Redo Log写入磁盘,不是写入数据文件。

Redo Log的特点:

  1. Redo Log是InnoDB存储引擎实现的,并不是所有存储引擎都有
  2. 不是记录数据页更新之后的状态,而是记录这个页做了什么改动,属于物理日志
  3. Redo Log的大小是固定的,前面的内容会被覆盖

除了Redo Log之外,还有一个跟修改有关的日志,叫做Undo Log(撤销日志或回滚日志),记录了事务发生之前的数据状态,分为insert Undo Log 和update Undo Log。如果修改数据时出现异常,可以用Undo Log来实现回滚操作(保持原子性)。

UPDATE 更新过程

有了Redo Log和Undo Log,我们来总结一下一个 Update 操作的流程。

update user set name = 'jason' where id = 1;
  1. 在执行前需要

    1. 连接器连接数据库
    2. 分析器通过词法分析和语法分析知道这是一条更新语句
    3. 优化器决定要使用的索引等
    4. 执行器负责具体的执行过程
  2. 事务开始从内存Buffer Pool或磁盘取到包含这条数据的数据页,返回给Server的执行器

  3. Server的执行器修改数据页的这一行数据的值为 jason

  4. 记录 name=jason123(原值)到Undo Log

  5. 记录 name=jason到Redo Log

  6. 调用存储引擎接口,记录数据页到Buffer Pool(修改 name=jason)

  7. 事务提交

大数据SQL调优专题——Hive执行原理 本文介绍了Hive,并通过源码梳理了Hive的执行原理。 阅读详情

相关推荐

MyBatis 动态 SQL 执行原理解析

MyBatis 在运行时根据参数的值和配置的条件逻辑,动态地构建最终的 SQL 语句,并将其传递给数据库驱动程序执行。MyBatis 是一款流行的 Java 持久化框架,它提供了强大的动态 SQL 功能,允许开发人员根据不同的条件和场景动态生成 SQL 语句。它会检查每个参数的值,并根据参数的类型和配置的条件逻辑,决定是否包含该参数对应的 SQL 片段。在运行时,MyBatis 会根据参数的值和配置的条件逻辑,动态地构建最终的 SQL 语句。它会将占位符替换为对应参数的值,从而生成可执行的 SQL 语句。

YOLOv7895的博客 352

SQL 的执行原理

SQL(结构化查询语言)是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。SQL是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统, 可以使用相同的结构化查询语言作为数据输入与管理的接口。

weixin_46653974的博客 1269

sql执行过程_原理_优化

oracle sql语句的执行过程和原理介绍,优化器模式,访问table的方式,表的连接方式及索引分类

SQL语句执行原理

假设我们有个最简单的表,表里只有一个ID字段,再执行下面一条查询语句: mysql> select * from T where ID=10; 我们看到的只是输入一条语句,返回一个结果,却不知道这条语句在MySQL内部的执行过程。为了解释这个问题,我们首先看一下MySQL的基本架构示意图,从中我们可以清楚的看到SQL语句在MySQL的各个功能模块中的执行过程。 1.MySQL的逻辑架构图 MySQL的逻辑架构图如下图所示: 大体上来说,MySQL可以分为Server层和存储引擎层两部分

Martin的博客 2057

SQL语句的执行原理分析

原理:第一步:应用程序把查询SQL语句发给服务器端执行。我们在数据层执行SQL语句时,应用程序会连接到相应的数据库服务器,把SQL语句发送给服务器处理。第二步:服务器解析请求的SQL语句。1:SQL计划缓存,经常用查询分析器的朋友大概都知道这样一个事实,往往一个查询语句在第一次运行的时候需要执行特别长的时间,但是如果你马上或者在一定时间内运行同样的语句,会在很短的时间内返回查询结果。  原因:1):服务器在接收到查询请求后,并不会马上去数据库查询,而是在数据库中的计划缓存中找是否有相对应的执行计划,如果存在,就直接调用已经编译好的执行计划,节省了执行计划的编译时间。2):如果所查询的行已经存在

智能车竞赛卡丁快跑组:自动驾驶与人车交互技术实战解析

本文深入解析了智能车竞赛卡丁快跑组的技术核心,重点探讨了自动驾驶与人车交互两大模块的实战方案。文章详细拆解了从环境感知、路径规划到语音识别、命令执行的完整流程,并分享了基于单片机平台的调试心法与赛场经验,为参赛者提供了一套从零开始、分步攻坚的系统性备赛指南。

f0g1h2的博客 1177

3. SQL底层执行原理详解

本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。

俺就是菜的很的博客 1252

基于USB总线的虚拟摄像头(UVC)原理简介

前面文章中我们分析了虚拟声卡的实现,在文章中我们展示了创建一个虚拟麦克风和虚拟扬声器的技术原理。完成了音频的虚拟化之后,这里就要谈论一下对于视频的虚拟化了——虚拟摄像头的实现。关于虚拟麦克风和虚拟扬声器的实现,可以参考。虚拟摄像头应用也是非常普遍的,例如云桌面远程摄像头的实现,直播技术。目前对于虚拟摄像头有三种实现方式:DirectShow虚拟摄像头,这个是一种比较古老的技术;在新版本应用中,该项技术基本失效了,尤其是UWP框架程序,DirectShow虚拟摄像头就失效了。

tianxilink的博客 5415

SQL底层执行原理

客户端——连接: 客户端跟服务端建立连接,如果不指定engine=引擎,默认InnoDB,还有MyISAM和Memory;在完成经典的TCP握手之后,连接器就开始认证身份,客户端如果长时间没动静,连接器就会自动将它断开。wait_timeout默认8小时,长连接:如果客户端持续有请求,则一直使用同一个连接。短连接:每次执行完很少的几次查询就断开连接,下次查询再重新建立一个; 1. 定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的............

qq_56754651的博客 688

【Qt笔记】1.VSCode搭建Qt运行环境

Qt6之后已经抛弃qmake,使用cmake。cmake相对qmake来说只有优点没有缺点。使用VSCode搭建完Qt的运行环境就能开开心心debug了.vscode需要使用的插件:2.Qt tools3.CMakec++插件可以不关注,缺啥都会提醒你.正常安装即可。

没有手牌的博客 2万+

【影像组学】用3Dslicer或Python提取影像组学特征

用3Dslicer或Python提取影像组学特征

abdslfwoeugp 1万+

SQL底层执行原理详解

MySQL的内部组件结构 Server 层和存储引擎层概念 MySQL层级详细说明 bin-log归档 MySQl执行原理和顺序

qq_44781222的博客 1767

PromptBio实战:如何用AI对话搞定转录组数据分析(附详细操作截图)

本文详细介绍了如何利用PromptBio平台通过AI对话完成转录组数据分析,无需编程基础即可实现从数据上传到结果解读的全流程。文章包含详细的操作截图和参数配置建议,帮助科研人员快速掌握这一生信分析工具,显著提升研究效率。

weixin_30872157的博客 133

8Hive SQL底层执行原理

本节结构采用宏观着眼,微观入手,从整体到细节的方式剖析 Hive SQL 底层原理。第一节先介绍 Hive 底层的整体执行流程,第二节介绍执行流程中的 SQL 编译成 MapReduce 的过程,第三节剖析 SQL 编译成 MapReduce 的具体实现原理。

qq_45972323的博客 1461

pytorch-cifar100学习资料汇总 - 基于PyTorch的CIFAR-100图像分类实践

pytorch-cifar100是一个基于PyTorch实现CIFAR-100数据集图像分类的开源项目。该项目实现了多种经典的深度学习网络模型,如ResNet、DenseNet、VGG等,为开发者提供了在CIFAR-100数据集上进行图像分类实验的代码范例。pytorch-cifar100项目为我们提供了在CIFAR-100数据集上进行图像分类实验的完整代码实现。无论你是想要学习PyTorch的使用,还是研究不同网络模型在CIFAR-100上的表现,这个项目都是一个很好的起点。

helloaiworld的博客 1123

【即插即用模块】Transformer篇 | AAAI 2026 | Circulant Attention:全新ViT自注意力范式,复杂度从O(N²) 降至O(NlogN)!

本文提出了一种基于频域优化的循环注意力模块(Circulant Attention),通过离散傅里叶变换(DFT)将传统自注意力中的矩阵乘法转化为频域元素乘法,显著降低了计算复杂度。该模块采用复数线性层适配频域特征,并引入门控调制机制增强表达能力,在保持全局依赖捕捉能力的同时,将复杂度从O(N²)降至O(NlogN)。实验表明,该模块在多种视觉任务中均能提升模型性能,且计算效率更高。适用于需要高效全局注意力的视觉Transformer架构,可作为传统自注意力的替代方案。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 152

3. Mybatis 中SQL 执行原理

这里有两种方式,一种为常用的 Spring 依赖注入 Mapper 的方式。另一种为直接使用 SqlSessionTemplate 执行 Sql 的方式。

长城的博客 1717

【AI大模型应用开发实战】大型语言模型评估指南白皮书(LLM Eval)

近年来,大型语言模型(LLM)在自然语言处理领域取得了重大进展,例如 GPT-3 和 Chat-GPT。这些模型经过大型数据集的训练,在文本相关任务中表现出卓越的能力,甚至超越了人类。本文将简要介绍如何验证 LLMs 性能的评估指标。自然语言处理(NLP)是人工智能的一个领域,涉及计算机和人类语言之间的交互。NLP 的基本任务之一是语言建模 (LM),它涉及构建统计模型来分析和生成自然语言。LM 已成为推进机器语言智能的关键方法,使机器能够执行机器翻译、情感分析和对话系统等任务。

AI天才研究院 1012

Sql语句的执行方式到底是怎样的?底层原理是什么?

SQL(Structured Query Language)语句的执行方式及其底层原理涉及多个层面,包括解析、优化、执行和结果返回。

长风破浪会有时的博客 1278

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

mysql的sql执行原理图_SQL语句的执行原理_MySQL

SQL语句的执行原理_MySQL原理:第一步:应用程序把查询SQL语句发给服务器端执行。我们在数据层执行SQL语句时,应用程序会连接到相应的数据库服务器,把SQL语句发送给服务器处理。第二步:服务器解析请求的SQL语句。1:SQL计划缓存,经常用查询分析器的朋友大概都知道这样一个事实,往往一个查询语句在第一次运行的时候需要执行特别长的时间,但是如果你马上或者在一定时间内运行同样的语句,会在很短的时...

weixin_35757736的博客 263

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Flink源码阅读之Sql-Client的执行原理

前言 sql-cli相信大家都用过,通过sql-client.sh embedded启动就会进入交互界面,每条sql都可以单独执行。在功能调试时非常方便,还有进入界面的那个大松鼠相当可爱。 脚本 先上脚本代码 #!/usr/bin/env bash ################################################################################ # Licensed to the Apache Software Foundation (ASF

weixin_41608066的博客 1124

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

能简述一下动态 SQL 的执行原理吗

当 MyBatis 启动时,会加载并解析映射文件(`Mapper.xml`),提取其中的 SQL 语句和动态标签(如 `<if>`、`<foreach>` 等)。2. **遍历 AST**:动态 SQL 处理器遍历抽象语法树,根据每个节点的类型(如 `<if>`、`<foreach>`)和条件判断,动态生成 SQL 片段。因为 `age` 为 `null`,所以跳过该片段。- **运行时构建**:在执行 SQL 时,根据传入的参数动态遍历 AST,生成 SQL 片段并拼接成完整的 SQL 语句。

2401_85327573的博客 1172

关于SQL语句的执行原理分析

5:接下来就是对数据库用户权限的验证,SQL语句语法,语义都正确,此时并不一定能够得到查询结果,如果数据库用户没有相应的访问权限,服务器会报出权限不足的错误给应用程序,在稍大的项目中,往往一个项目里面会包含好几个数据库连接串,这些数据库用户具有不同的权限,有的是只读权限,有的是只写权限,有的是可读可写,根据不同的操作选取不同的用户来执行,稍微不注意,无论你的SQL语句写的多么完善,完美无缺都没用。这只能基本消除SQL缓存的影响,目前好像没有完全消除缓存的方案,如果大家有,请指教。

xiaoweids的博客 187

一条SQL的执行原理

mysql一条sql执行原理

运维 3235

hive底层原理 sql执行过程_SQL查询的底层运行原理分析

SQL 语言无处不在。SQL 已经不仅仅是技术人员的专属技能了,似乎人人都会写SQL,就如同人人都是产品经理一样。如果你是做后台开发的,那么CRUD就是家常便饭。如果你是做数仓开发的,那么写SQL可能占据了你的大部分工作时间。我们在理解 SELECT 语法的时候,还需要了解 SELECT 执行时的底层原理。只有这样,才能让我们对 SQL 有更深刻的认识。本文分享将逐步分解SQL的执行过程...

weixin_35062801的博客 489
上一篇: Mysql后台线程
下一篇: Mysql索引(一)
geek-wmy
博客等级 码龄9年 322粉丝 126原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值