Mysql中select查询语句的执行过程

目录

1、介绍

1.1、组件介绍

1.2、Sql执行顺序

2、执行流程

2.1. 连接与认证

2.2. 查询缓存

2.3. 语法解析(Parser)

2.4、执行sql

1. 预处理(Preprocessor)

2. 查询优化器(Optimizer)

3. 执行器(Executor)

2.5. 存储引擎交互

2.6. 返回结果

3、示例流程(SELECT 查询)

4、常见问题与优化


前言

        MySQL 查询语句可以分为 Server 层存储引擎层。而 Server 层包括连接器、查询缓存、解析器、预处理器、优化器、执行器等,

        最后 Server 层再通过 API 接口形式调用对应的存储引擎层提供的接口来执行增删改查操作。

如下图所示:

更多mysql的介绍,可参考:聊聊对Mysql数据库的见解_如何更好的理解mysql-CSDN博客


1、介绍

关于sql语句在执行过程中,可能会涉及到以下的组件来进行相互的调用。

1.1、组件介绍

组件及其作用,可参考:

1.2、Sql执行顺序

        在 SQL 中,select 语句的语法结构看似是按照关键字书写顺序执行的(如 select ... from ... where ...),但 实际执行顺序 与语法顺序并不完全一致。

如下图所示:

⚠️注意:

        在包含子查询的 SQL 中,子查询本身也是一个完整的 select 语句,其内部仍然遵循上述执行顺序。外部查询的执行顺序会以子查询的最终结果为输入继续执行。

为了更好地理解这个顺序,我们可以从“数据流”的角度思考:

  1. FROM:首先确定从哪个表或视图中读取数据。
  2. WHERE:在获取原始数据后,先进行行级过滤,减少后续处理的数据量。
  3. GROUP BY:将过滤后的数据按指定字段分组,为聚合操作做准备。
  4. HAVING:在分组后,进一步过滤不满足条件的组。
  5. SELECT:确定最终返回的字段(包括常量、表达式、聚合函数等)。
  6. ORDER BY:对最终结果进行排序。
  7. LIMIT:限制返回的记录数量。

如下图所示:​​​​​​​


2、执行流程

        一个完整的执行流程包括以下组件,连接器、缓存、解析器、优化器、执行器存储引擎组成。

如下图所示:

2.1. 连接与认证

        MySQL 服务端和客户端的通信方式采用的是半双工协议。

客户端连接:客户端通过协议(如 TCP/IP、Socket)与 MySQL 服务端建立连接。

认证:服务端验证用户身份(用户名、密码、权限)。如果验证失败,连接终止。

权限检查:确认用户是否有权限执行当前查询(如 SELECT 权限)。

常见的通信方式主要可以分为三种:单工,半双工,全双工。

单工:

        通信的时候,数据只能单向传输。比如说遥控器,我们只能用遥控器来控制电视机,而不能用电视机来控制遥控器。

半双工:

        通信的时候,数据可以双向传输,但是同一时间只能有一台服务器在发送数据,当 A 给 B 发送数据的时候,那么 B 就不能给 A
发送数据,必须等到 A 发送结束之后,B 才能给 A 发送数据。比如说对讲机。

全双工:

        通信的时候,数据可以双向传输,并且可以同时传输。比如说我们打电话或者用通信软件进行语音和视频通话等。

        半双工协议让 MySQL 通信简单快速,但是也在一定程度上限制了 MySQL 的性能,因为一旦从一端开始发送数据,另一端必须要接收完全部数据才能做出响应。

        所以当批量插入的时候尽量拆分成多次插入而不要一次插入太大数据,同样的查询语句最好也带上 limit 限制条数,避免一次返回过多数据。

        MySQL 单次传输数据包的大小可以通过变量 max_allowed_packet 控制,默认大小为 64MB(5.7 版本默认只有 4MB)。

执行以下语句查看 max_allowed_packet 变量大小:

2.2. 查询缓存

缓存命中检查

        如果开启了查询缓存(Query Cache),MySQL 会直接检查是否有完全相同的查询结果缓存。

        命中:直接返回缓存结果。

        未命中:进入后续流程,并可能将结果写入缓存(取决于配置)。

        注意:MySQL 8.0 已移除查询缓存功能。

移除原因:

        因为 MySQL 的缓存使用条件非常苛刻,是通过一个大小写敏感的哈希值去匹配的,这样就是说一条查询语句哪怕只是有一个空格不一致,都会导致无法使用缓存。而且一旦表里面有一行数据变动了,那么关于这种表的所有缓存都会失效,所以一般我们都是不建议使用缓存。

        在 MySQL 8.0 版本之前缓存也是默认关闭的,可以通过变量 query_cache_type 进行控制。

2.3. 语法解析(Parser)

词法分析:将 SQL 语句拆分为 token(如关键字、标识符、操作符等)。

语法分析:根据 SQL 语法树规则,检查语句合法性(如 SELECT * FROM table 是否符合语法)。

生成抽象语法树(AST):将 SQL 转换为数据库可理解的内部结构。

        整个sql语句会被分割成:select,name,from,table,where,id,=,1这几个字符。并且能识别出关键字和非关键字,然后根据 sql 语句生成一个数据结构,也叫做解析树。

如下图所示:

2.4、执行sql

如下图所示:

1. 预处理(Preprocessor)

  • 语义检查
    • 检查表、列是否存在。
    • 验证权限(如用户是否有权限访问指定的表或列)。
    • 替换别名、处理函数等。
  • 生成逻辑查询计划:将 AST 转换为逻辑执行计划(如select a from t1 where b = 5)。

2. 查询优化器(Optimizer)

        其目标是生成最优的执行计划即最小资源消耗、最快响应时间)。

优化步骤

        选择访问路径:决定是否使用索引(如全表扫描 vs 索引扫描)。如果有多个索引,选择最合适的索引。

        连接顺序优化(针对多表查询):决定表的连接顺序(如 A JOIN B JOIN C 的顺序)。使用动态规划或代价模型(Cost Model)计算最优顺序。

        其他优化:优化子查询(如转换为 JOIN)。优化排序(ORDER BY)和分组(GROUP BY)。常量传播、条件简化等。

输出执行计划:生成物理执行计划(如使用哪个索引、连接算法等)。

3. 执行器(Executor)

  • 执行查询计划
    • 调用存储引擎接口(如 InnoDB、MyISAM)获取数据。
    • 根据执行计划逐层处理(如过滤、排序、分组)。
  • 权限二次检查:确保用户对访问的数据有权限。
  • 数据处理
    • 读取数据行(通过全表扫描或索引扫描)。
    • 应用 WHERE 条件过滤。
    • 对结果进行排序、分组、聚合等操作。

2.5. 存储引擎交互

  • 存储引擎接口:MySQL 通过统一的接口(Handler API)与存储引擎交互。
  • InnoDB 的处理
    • 通过 B+ 树索引定位数据。
    • 处理事务(如锁机制、MVCC)。
    • 返回符合条件的记录。
  • 其他引擎:如 MyISAM 的处理方式不同(无事务支持)。

2.6. 返回结果

  • 结果集组装:将处理后的数据按用户指定的格式(如 SELECT 字段)组装。
  • 分页处理:若涉及 LIMIT 或分页,截取对应的数据。
  • 返回客户端
    • 一次性返回(小结果集)。
    • 流式返回(大结果集,通过网络分批次传输)。

        MySQL 将查询结果返回是一个增量的逐步返回过程

        当处理完所有查询逻辑并开始执行查询并且生成第一条结果数据的时候,MySQL 就可以开始逐步的向客户端传输数据了。这么做的好处是服务端无需存储太多结果,从而减少内存消耗。


3、示例流程(SELECT 查询)

以 SELECT * FROM users WHERE id = 1; 为例:

  1. 客户端连接数据库。
  2. 检查查询缓存(未命中)。
  3. 解析 SQL 语法,生成 AST。
  4. 预处理:检查 users 表和 id 列是否存在。
  5. 优化器选择 id 索引进行查找。
  6. 执行器调用 InnoDB 引擎,通过索引定位到 id=1 的记录。
  7. 返回结果给客户端。

4、常见问题与优化

  • 慢查询:检查执行计划(使用 EXPLAIN),优化索引或调整查询逻辑。
  • 全表扫描:添加合适的索引或优化查询条件。
  • JOIN 性能:调整连接顺序或使用索引。
  • 缓存失效:频繁更新的表可能导致缓存命中率低(MySQL 8.0 后不再依赖此)。


参考文章:

1、聊聊对Mysql数据库的见解_如何更好的理解mysql-CSDN博客

2、一条 select 语句的执行过程_一个select语句执行过程-CSDN博客

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

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

相关文章

Acrobat DC v25.001 最新专业版已破,像word一样编辑PDF!

在数字化时代,PDF文件以其稳定性和通用性成为了文档交流和存储的热门选择。无论是阅读、编辑、转换还是转曲,大家对PDF文件的操作需求日益增加。因此,一款出色的PDF处理软件不仅要满足多样化的需求,还要通过简洁的界面和强大的功能…

CSS中justify-content: space-between首尾贴边中间等距(两端元素紧贴左右边缘,中间元素等距均匀分布)

justify-content: space-between; 是 CSS Flexbox 布局中的一个属性值,主要作用是在弹性容器的主轴方向上均匀分布子元素,具有以下核心特性: 作用效果: 首尾贴边 第一个子元素紧贴容器起始端 最后一个子元素紧贴容器结束端 中…

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…

全球知名具身智能/AI机器人实验室介绍之AI FACTORY基于慕尼黑工业大学

全球知名具身智能/AI机器人实验室介绍之AI FACTORY基于慕尼黑工业大学 TUM AI FACTORY,即KI.FABRIK,是德国慕尼黑工业大学(TUM)在巴伐利亚州推出的一个旗舰项目,旨在打造未来工厂,将传统工厂转变为由人工智…

DRV8833 电机控制芯片

引脚分配如图: 要让芯片运行需要将STBY拉高 IN1 IN2 分两组 对应 AO BO,同时拉高电平可以进行刹车(慢速衰减。 芯片本身引脚定义: 控制真值表:

如何通过git命令查看项目连接的仓库地址?

要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…

区块链技术相关

区块链技术参考:区块链 多领域 一、区块链技术演进与2025年核心突破 2025年,区块链技术已从单一分布式账本演变为融合人工智能、物联网、隐私计算的多维技术栈。零知识证明(ZKP)在性能优化上取得关键进展,以太坊等主流…

C语言字符数组输入输出方法大全(附带实例)

在 C语言中,字符数组是一种特殊的数组,用于存储和处理字符串。理解字符数组的输入和输出操作对于初学者来说至关重要,因为这是处理文本数据的基础。 字符数组的定义与初始化 在讨论输入输出之前,我们先来回顾一下字符数组的定义…

前端下载文件,文件打不开的问题记录

需求: 下载是很常见的接口,但是经常存在下载的文件异常的问题。此处记录一个常见的错误。 分析: 1、接口请求需要配置{responseType: ‘blob’},此时要求返回的格式为blob,进而进行下载。 const res await axios.…

HttpServletRequest常用方法

方法说明示例String getMethod()获取请求的 HTTP 方法(如 GET、POST 等)。request.getMethod() 返回 "GET"String getRequestURI()获取请求的 URI(路径部分,不包括域名和协议)。请求 http://localhost:8080/…

day46python打卡

知识点回顾: 不同CNN层的特征图:不同通道的特征图什么是注意力:注意力家族,类似于动物园,都是不同的模块,好不好试了才知道。通道注意力:模型的定义和插入的位置通道注意力后的特征图和热力图 内…

杭州AI落地赚钱方案:30日行动计划

本计划基于《AI时代赚钱的第一性原理指南》,并针对杭州市的产业特色(电商、直播、文旅)进行深度定制。我们的目标不是空想,而是从明天开始就能一步步执行的蓝图。 方案一:电商/直播AI赋能工作室 这个方案完美结合了路…

MyBatis04:SpringBoot整合MyBatis——多表关联|延迟加载|MyBatisX插件|SQL注解

目录 一、多表关联 1、数据库表结构 2、javaBean类 3、mapper接口 4、sqlMapper文件 5、测试 二、延迟加载 1、解决什么问题 2、嵌套查询 3、延迟加载 三、逆向工程MybatisX插件 1、下载插件 1. 通过 JetBrains 插件市场下载(推荐) 2. 手动…

PySpark、Plotly全球重大地震数据挖掘交互式分析及动态可视化研究

全文链接:https://tecdat.cn/?p42455 分析师:Yapeng Zhao 在数字化防灾减灾的时代背景下,地震数据的深度解析成为公共安全领域的关键议题。作为数据科学工作者,我们始终致力于通过技术整合提升灾害数据的应用价值(点击…

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…

MVC与MVP设计模式对比详解

MVC(Model-View-Controller)和MVP(Model-View-Presenter)是两种广泛使用的分层架构模式,核心目标是解耦业务逻辑、数据和界面,提升代码可维护性和可测试性。以下是它们的对比详解: MVC 模式&…

Node.js 项目调试指南

Node.js 项目调试指南 🧭 一、调试工具和方式总览 方式难度场景说明console.log 调试★简单问题定位最常见,但效率低debug 模块★★模块化输出日志支持命名空间的调试日志VSCode 断点调试★★★跟踪函数调用、变量状态推荐使用node inspect / ndb★★★…

Spring Boot 启动流程及配置类解析原理

Spring Boot 是一个基于 Spring 框架的开源框架,旨在简化 Spring 应用的配置和部署。通过提供约定优于配置的原则,Spring Boot 大大降低了 Java 企业级应用的开发复杂度。本文将详细介绍 Spring Boot 的启动流程及其配置类的解析原理,帮助开发…

Flask 核心概念速览:路由、请求、响应与蓝图

一、路由参数与请求方法 Flask 路由允许定义多种参数类型,并通过 methods 属性限制请求方法。 1. 路由参数类型: 除了默认的 string,Flask 还支持: int: 匹配整数,自动转换为 Python int 类型。非数字输入会返回 404。 float: 匹配浮点数,自动转换为 Python float 类型…

Beckhoff(倍福)PLC 顺控程序转换条件解读

一、请求机器人上件步 二、程序代码解释:1、程序代码1: 1、程序代码: fbVar_TonDelay2(IN : (bInPartPresentLeft AND bInPartPresentRight), PT : T#100MS);(* Go to the next step *) stVar_SEQ.bTOK : stVar_SEQ.bRELEASE AND(stGV_SYS_ELEMENTS.ar…