首页 >> 基础教程

mysql中一条查询语句是如何执行的?

        MySQL 中一条查询语句(如 SELECT)的执行是一个分层协作的过程,涉及多个核心组件。以下是详细执行流程(以 SELECT * FROM users WHERE id = 10; 为例):

1. 连接建立与认证

  • 客户端发起请求:通过 MySQL 协议(如 TCP/IP)连接服务器。

  • 连接层处理

    • 验证用户名、密码、主机权限。

    • 分配线程(或从线程池复用)处理该连接。

    • 若启用 wait_timeout,闲置连接会被自动关闭。

2. 查询缓存(仅 MySQL 5.7 及之前)

  • 检查缓存:计算查询语句的哈希值,查询缓存(Key-Value 结构)。

  • 若命中:直接返回结果(权限验证后)。

  • 若未命中/MySQL 8.0+:跳过此步骤(8.0 已移除该功能)。

3. 解析与预处理

  • 解析器(Parser)

    • 词法分析:拆分 SQL 为 tokens(如 SELECT*FROMusers)。

    • 语法分析:构建语法树,检查是否符合 SQL 语法规则(如关键词顺序)。

  • 预处理器

    • 检查表和列是否存在。

    • 解析 * 为所有列名。

    • 验证权限(用户是否有权访问 users 表)。

4. 查询优化器

  • 核心任务:生成成本最低的执行计划

  • 优化过程

    • 全表扫描:读取所有行(成本高)。

    • 使用索引:通过 B+ 树定位 id=10(成本低)。

    • 分析可用索引(如 PRIMARY KEY(id))。

    • 估算不同执行方式的成本:

    • 选择索引并确定 JOIN 顺序(若涉及多表)。

  • 输出:生成执行计划树(可通过 EXPLAIN 查看)。

5. 执行器

  • 调度执行

    • 根据优化器的计划调用存储引擎接口

    • 打开表,检查执行权限。

  • 执行流程

执行器 -> 存储引擎: “读取 users 表 id=10 的行”
存储引擎 -> 执行器: 返回符合条件的行

6. 存储引擎处理

  • InnoDB 引擎为例

    1. 检查 id=10 是否在 Buffer Pool(内存缓存)中:

      1. 若存在:直接返回数据。

      2. 若不存在:从磁盘 .ibd 文件读取页到 Buffer Pool。

    2. 通过索引查找

      1. 使用主键索引(B+ 树)定位 id=10 的数据页位置。

      2. 若涉及二级索引,需回表查询主键索引。

    3. 加锁机制

      1. 默认 RR 隔离级别:对读取行加临键锁(Next-Key Lock)防止幻读。

      2. 若为读提交(RC):加行锁

7. 结果返回

  • 执行器处理结果

    • 将存储引擎返回的行数据组合成结果集。

    • 若启用慢查询日志且超阈值,记录该查询。

  • 返回客户端

    • 通过连接线程的输出缓冲区逐步发送结果。

    • 客户端接收并显示数据(如命令行或应用程序)。

性能关键点

  1. 连接管理:线程创建/销毁开销大,建议用连接池(如 HikariCP)。

  2. 优化器决策:索引失效或统计信息不准会导致全表扫描(需定期 ANALYZE TABLE)。

  3. Buffer Pool:命中率低时磁盘 I/O 压力大(可调整 innodb_buffer_pool_size)。

  4. 网络传输:避免 SELECT *,只取必要列减少数据传输量。

  5. 锁竞争:长时间未提交的事务会阻塞查询(监控 Innodb_row_lock_waits)。

调试工具

  • EXPLAIN [SQL]:查看执行计划。

  • SHOW PROFILES;:分析各阶段耗时。

  • 慢查询日志:定位性能瓶颈。


最新文章
InnoDB 和 MyISAM 主要有什么区别?2025-07-06
mysql存储引擎应该怎么选择?2025-07-06
mysql的几种存储引擎2025-07-06
MySQL 的段区页行2025-07-06
一条更新语句是如何执行的?2025-07-06
mysql中一条查询语句是如何执行的?2025-07-02
MySQL基础架构及执行流程解析2025-07-02
MySQL SQL语法树解析过程详解2025-07-02
mysql中SQL 的隐式数据类型转换?2025-07-01
MySQL 第 3-10 条记录怎么查?2025-06-30
备案号:蜀ICP备2023042032号-1