当前位置: 首页 > article >正文

简单说说MySQL中 SELECT 语句执行流程

流程讲解

MySQL 中 SELECT 语句的执行流程分为多个步骤,通常从用户发出查询请求到 MySQL 返回结果包含以下过程:

  1. 客户端/服务器通信
    用户向 MySQL 服务器发送 SELECT 查询语句。

  2. 查询解析(Parser)
    MySQL 收到 SQL 语句后,会将查询语句进行词法和语法分析。词法分析器将 SQL 语句拆解为关键字、表名、字段名等元素,然后语法分析器根据 MySQL 语法规则检查语句的合法性

  3. 预处理
    语法解析后,MySQL 会对查询语句进行预处理,例如:检查表、列是否存在,验证用户的权限等

  4. 查询优化器(Optimizer)
    这是 MySQL 查询性能的关键步骤。优化器决定如何执行查询,例如选择最优的索引,决定表连接顺序,选择全表扫描还是使用索引等。MySQL 的优化器会生成多个执行计划,选择成本最低的计划。

  5. 查询执行器(Executor)
    执行器根据优化器生成的执行计划去执行查询语句。执行器逐步获取数据,按优化器的指示选择适当的访问方式,如是否使用索引,是否需要回表等。

  6. 存储引擎层交互
    MySQL 是多存储引擎的系统。执行器根据存储引擎的接口与底层存储引擎交互,获取表中的数据。不同的存储引擎(如 InnoDB、MyISAM)处理查询的方式可能不同。

  7. 查询缓存(如果启用)
    在 MySQL 8.0 之前,如果查询缓存是开启的且查询结果在缓存中,那么 MySQL 可以直接从缓存中返回结果,而不需要继续执行查询。MySQL 8.0 已移除了查询缓存。

  8. 返回结果
    查询执行完毕后,MySQL 将结果返回给客户端。

select 实例分析

select * from tb_student A where A.age=‘18’ and A.name=’ 张三 ';

针对 SELECT * FROM tb_student A WHERE A.age='18' AND A.name='张三'; 这条 SQL 语句,MySQL 的执行流程可以分为如下几个步骤:

1. 客户端/服务器通信

用户在客户端执行该查询,SQL 语句通过网络传递到 MySQL 服务器。

2. 查询解析(Parser)

MySQL 服务器接收到查询语句后,会对 SQL 进行词法和语法解析。

  • 词法解析:SQL 语句被拆分为单个关键字或标识符,如 SELECT*FROMtb_studentWHEREA.age 等。
  • 语法解析:MySQL 根据 SQL 语法规则检查该查询语句的结构是否正确。如果语法有误,查询会立即失败。

3. 预处理

  • 表和列的合法性检查:MySQL 预处理器会检查表 tb_student 是否存在,字段 agename 是否在表 tb_student 中。
  • 用户权限检查:MySQL 还会验证当前用户是否有权限访问 tb_student 表并执行查询。

4. 查询优化器(Optimizer)

MySQL 的查询优化器将决定查询的最佳执行方式。对于这条查询,优化器可能做的工作包括:

  • 选择合适的索引:如果 agename 字段上有索引,优化器可能决定使用索引来加速查询。
  • 生成执行计划:优化器会评估多个执行计划,比如先通过 age='18' 过滤数据还是通过 name='张三' 过滤,然后选择代价最小的方案。例如,如果 agename 都有索引,优化器可能会选择一个索引作为主导。

5. 查询执行器(Executor)

查询执行器根据优化器生成的执行计划执行查询。假设 age 字段上有索引,那么执行器会:

  • 使用索引快速找到 age=18 的记录。
  • 然后根据 name='张三' 的条件进一步筛选数据。

6. 存储引擎层交互

执行器与底层存储引擎(如 InnoDB)交互,按执行计划获取数据。存储引擎会根据执行器的指令进行:

  • 读取操作:如果涉及到索引查找,存储引擎可能只需要扫描部分数据,而不是全表扫描。
  • 回表操作:如果使用了覆盖索引且所需字段都能从索引中获取,则直接返回;否则可能需要回表(通过主键索引)来获取 *(即所有列)。

7. 过滤和处理

执行器对查询结果进行过滤,确保返回的数据满足 age='18'name='张三' 两个条件。MySQL 将把符合条件的数据组装成查询结果集。

8. 返回结果

查询结果被发送回客户端,完成 SQL 语句的执行。


http://www.kler.cn/a/311588.html

相关文章:

  • 2411C++,C++26反射示例
  • Unity3D
  • ❤React-JSX语法认识和使用
  • Day09 C++ 存储类
  • Flink CDC(SQL Client)连接 MySQL 数据库教程
  • WPF中的ResizeMode
  • 最新动态一致的文生视频大模型FancyVideo部署
  • 【MySQL】MySQL 在 Centos 7环境安装
  • Hive自定义函数——简单使用
  • C#广泛应用的简洁匿名函数Lambda 表达式
  • 基于Python的自然语言处理系列(12):使用TorchText和LSTM进行序列到序列(seq2seq)翻译
  • LVGL 控件之仪表盘(lv_meter)
  • Learn ComputeShader 15 Grass
  • 【JVM】垃圾回收
  • 派遣函数 - 缓冲区设备模拟文件读写
  • 服务器数据恢复—raid5阵列热备盘上线失败导致阵列崩溃的数据恢复案例
  • redis为什么不使用一致性hash
  • 向日葵好用吗?4款稳定的远程控制软件推荐。
  • 关于交叉编译移植到Debian开发板的一些随笔
  • gbase8s存储过程一些隐藏的错误写法
  • docker镜像源
  • info 命令:查看命令手册
  • 案例分析-Stream List 中取出值最大的前 5 个和最小的 5 个值
  • 动态内存
  • 7.Java高级编程 多线程
  • flutter Dio发送post请求