一条 SQL 语句在 MySQL 中的完整执行流程

发布时间:2026/7/12 10:54:50
一条 SQL 语句在 MySQL 中的完整执行流程 MySQL 两层架构与 SQL 执行全流程详解架构总览MySQL 整体分为两层架构Server 服务层包含连接器、分析器、优化器、执行器等负责 SQL 的解析与执行流程。存储引擎层如 InnoDB、MyISAM 等专注于数据的实际读写操作。本文将分别以查询语句SELECT和更新语句INSERT/UPDATE/DELETE为例详细拆解 MySQL 的完整执行流程。一、查询 SQL 执行的五大阶段SELECT1. 连接器 Connector建立连接与权限校验客户端通过 TCP 三次握手与 MySQL 服务建立长连接。校验账号和密码错误则直接返回 Access denied。读取权限表缓存当前连接的库、表权限如用 GRANT 修改权限需重连才生效。空闲连接默认 8 小时后自动断开参数 wait_timeout长连接堆积可能导致内存泄漏建议定期重连或使用 mysql_reset_connection 重置状态。补充说明MySQL 8.0 已移除查询缓存5.x 版本中此阶段会优先匹配缓存但缓存失效率高实际命中率较低。2. 分析器 Analyzer词法、语法解析与 AST 生成以 SELECT * FROM user WHERE id 1 为例词法分析将 SQL 字符串拆分为关键字如 SELECT、FROM、WHERE、字段名、常量值。语法分析校验语句结构合法错误时抛出 You have an error in your SQL syntax。输出抽象语法树AST结构化描述 SQL 逻辑为后续优化做准备。3. 优化器 Optimizer生成最优执行计划索引选择多索引场景下依据统计信息估算扫描行数与 IO 成本选取最优索引。多表 JOIN 优化调整表连接顺序通常采用“小表驱动大表”原则。SQL 改写如子查询转 JOIN、常量折叠、条件下推、移除无用字段等。输出执行计划可通过 EXPLAIN 查看如 type 扫描类型、key 使用索引、rows 预估行数。⚠️ 优化器依赖表统计信息若统计信息过期或数据分布极端可能选错索引。可用 FORCE INDEX、STRAIGHT_JOIN 强制指定但不建议长期滥用 Hint。4. 执行器 Executor权限校验与存储引擎调用再次校验当前用户对目标表的查询权限。通过存储引擎统一 Handler API 向 InnoDB 下发数据读取指令。逐行读取数据过滤 WHERE 条件组装结果集。5. 存储引擎层 InnoDB底层数据读取主键查询如 WHERE id1直接走聚集索引 B 树叶子节点一次性读取完整行无需回表。普通字段查询如 WHERE namexxx通过二级索引获取主键 ID再回表查询完整数据。最终数据逐层返回至客户端。二、更新 SQLINSERT/UPDATE/DELETE与查询的核心差异连接器、分析器、优化器流程一致主要差异在执行器与存储引擎层1. 日志写入三大日志 两阶段提交 2PCundo log记录修改前数据用于事务回滚和 MVCC 快照读。redo logWAL 预写日志先写物理日志保障宕机可恢复提升性能由 innodb_flush_log_at_trx_commit 控制刷盘策略。binlogServer 层逻辑日志记录完整 SQL/行变更服务于主从复制与数据恢复。两阶段提交2PC保证日志一致性Prepare 阶段写入 redo log标记为 Prepare。Commit 阶段binlog 落盘后将 redo log 标记为 Commit。宕机恢复redo 处于 Prepare 时若 binlog 记录完整则提交否则回滚确保主从一致。2. 锁机制InnoDB 默认行级锁基于 MVCC 实现读写不阻塞。更新前读取目标行并加排他锁事务提交时统一释放。若更新无索引会退化为表锁严重影响并发。3. 缓冲池脏页机制修改只影响内存缓冲池中的脏页不会立即刷盘。后台 Checkpoint 线程定期批量将脏页写入磁盘释放 redo log 空间。三、面试精简口述版一条 SQL 执行分为 Server 四层 InnoDB 引擎层连接器TCP 连接、账号密码、权限校验注意长连接内存泄漏。分析器拆分 SQL 关键字、校验语法生成抽象语法树。优化器评估多索引、JOIN 顺序改写 SQL 生成最优执行计划。执行器二次校验权限调用 InnoDB Handler 接口读取数据。InnoDB 引擎基于 B 树索引读取数据结果返回客户端。若为增删改语句执行阶段额外涉及 undo/redo/binlog 三大日志通过两阶段提交保证日志一致性加行锁保障事务隔离依托 WAL 机制平衡性能与安全。