一条mysql的查询语句是怎样执行的?

MySQL 查询语句的执行过程是一个多阶段的复杂流程,涉及多个组件协同工作。以下是核心步骤的详细说明(以常见的 InnoDB 存储引擎为例):


1. 连接器(Connector)

  • 功能:管理客户端连接、身份认证和权限校验。
  • 流程
    • 客户端发起 TCP 连接(如 mysql -u root -p)。
    • 验证用户名、密码及权限(权限信息在连接建立时缓存,后续操作基于此缓存)。
    • 建立连接后,如果长时间无操作,连接器会自动断开(由 wait_timeout 参数控制)。

2. 查询缓存(Query Cache) (MySQL 8.0 已移除)

  • 历史作用:缓存 SELECT 语句及其结果。
  • 淘汰原因
    • 任何表更新(INSERT/UPDATE/DELETE)都会导致该表相关的缓存全部失效。
    • 缓存命中率低,在高并发场景下维护缓存反而降低性能。

注:MySQL 8.0 开始此功能已被删除


3. 解析器(Parser)

  • 词法分析 :将 SQL 字符串拆分为 tokens(识别关键词、表名、列名等)。
    • 例如:SELECT id FROM users → 拆解为 [SELECT] [id] [FROM] [users]
  • 语法分析 :检查 SQL 语法是否正确,生成解析树(Parse Tree)
    • 若语法错误(如缺少关键字),抛出 You have an error in your SQL syntax 异常。

4. 预处理器(Preprocessor)

  • 语义检查
    • 验证表名、列名是否存在。
    • 检查列的数据类型是否兼容。
    • 解析 * 为所有列名(如 SELECT *)。
  • 权限校验:验证用户对目标表的操作权限。
  • 输出:生成新的解析树(用于优化器)。

5. 优化器(Optimizer)

  • 核心任务 :将解析树转化为最优执行计划
  • 优化策略
    • 选择索引:基于成本模型(Cost Model)选择最低成本的索引(如全表扫描 vs 索引扫描)。
    • JOIN 优化:决定多表 JOIN 的顺序(如小表驱动大表)。
    • 子查询优化:将子查询转化为 JOIN 等高效形式。
    • 表达式简化 :如 WHERE 1=1 被直接移除。
  • 输出 :生成执行计划(Execution Plan) (可通过 EXPLAIN 查看)。

6. 执行器(Executor)

  • 角色:调用存储引擎接口执行计划。
  • 流程
    1. 检查用户对表的执行权限(若未通过则返回权限错误)。
    2. 根据执行计划调用存储引擎的读写接口。
    3. 逐步获取数据并处理(如排序、聚合等)。
    4. 生成结果集。

7. 存储引擎(Storage Engine)

  • 作用 :真正执行数据读写(以 InnoDB 为例):
    • 读写流程
      • 先查询Buffer Pool (内存缓存池):
        • 若数据在内存中,直接返回。
        • 若不在,从磁盘加载到 Buffer Pool 再返回(遵循 LRU 原则)。
      • 磁盘读写以页(Page,默认 16KB) 为单位。
    • 索引查询
      • 使用 B+ 树索引定位数据(如通过主键索引快速查找行)。
    • 事务支持
      • 写操作会记录 redo log (保证持久性)和 undo log(保证回滚)。
      • 通过锁机制(行锁、间隙锁)和 MVCC 实现隔离性。

8. 结果返回

  • 结果集处理
    • 结果缓存在内存(如 net_buffer,默认 16KB)。
    • 分段返回客户端(避免一次性传输大量数据)。
  • 输出:将最终结果返回给客户端(命令行/GUI 工具等)。

流程图解

客户端 连接器
认证+权限 解析器
词法/语法分析 预处理器
语义检查 优化器
生成执行计划 执行器
调用存储引擎接口 存储引擎
读写数据 返回结果集


关键注意事项

  1. 权限验证两次
    • 连接器验证连接权限。
    • 执行器验证表操作权限。
  2. Buffer Pool 核心作用
    • 减少磁盘 I/O,90% 以上的操作在内存中完成。
  3. 日志先行(WAL)
    • 所有数据修改先写 redo log,再写磁盘(提高写入性能)。
  4. 索引的重要性
    • 优化器依赖索引选择高效路径,无索引可能导致全表扫描。

通过理解这一流程,可以更有效地进行 SQL 优化(如索引设计、避免全表扫描)和故障排查(如权限问题、语法错误)。

相关推荐
w***765510 分钟前
用docker启动mysql步骤
mysql·docker·容器
翔云12345619 分钟前
MySQL 机器重启后,gtid_executed 是如何初始化的
数据库·mysql·adb
JAVA学习通34 分钟前
Mysql进阶---存储过程&变量&SQL编程
数据库·mysql
阿里云大数据AI技术38 分钟前
朝阳永续基于阿里云 Milvus 构建金融智能投研产品“AI 小二”
数据库·人工智能
百***49001 小时前
Redis-配置文件
数据库·redis·oracle
老纪的技术唠嗑局1 小时前
OceanBase 年度发布会 Hands-on AI Workshop 回顾
数据库
艾体宝IT1 小时前
艾体宝干货 | Redis Python 开发系列#5 高可用与集群部署指南
数据库
d***95621 小时前
docker 安装 mysql
mysql·adb·docker
雨中飘荡的记忆1 小时前
MySQL 优化实战
java·mysql
3***89191 小时前
开放自己本机的mysql允许别人连接
数据库·mysql·adb