一条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 优化(如索引设计、避免全表扫描)和故障排查(如权限问题、语法错误)。

相关推荐
程序猿乐锅10 小时前
【Tilas|第三篇】多表SQL语句
数据库·经验分享·笔记·学习·mysql
Navicat中国11 小时前
使用 Navicat 导入向导导入 Excel 数据时,系统提示导入成功,表中也能看到数据,但行数统计显示为 0,这是什么原因?
数据库·excel·导入
gmaajt11 小时前
Golang怎么做国际化多语言_Golang i18n教程【核心】
jvm·数据库·python
折哥的程序人生 · 物流技术专研11 小时前
从“卡死”到“秒过”:WMS销售数据跨库回填的极限优化之旅
数据库·机器学习·oracle
李可以量化11 小时前
DeepSeek 量化交易实战:用标准化提示词模板实现 AI 辅助交易决策
大数据·数据库·人工智能
maqr_11011 小时前
CSS如何利用Sass定义全局阴影方案_通过变量实现统一CSS风格
jvm·数据库·python
m0_6138562911 小时前
uni-app怎么做类似于美团的商家评价星级 uni-app五星评分组件制作【实战】
jvm·数据库·python
Irene199112 小时前
大数据开发语境下,SQL 模式名,映射关系 - - 概念理解
大数据·数据库·sql
顾随12 小时前
(二)kettle--输入与输出
javascript·数据库·kettle
2401_8330336212 小时前
如何修复固定定位头部容器中悬浮下拉菜单的错位问题
jvm·数据库·python