SQL语句在MySQL中的执行过程
搞清 SQL 执行链路,才能理解权限校验、解析、优化、执行与结果返回各阶段在做什么。
执行阶段概览
- 连接器:TCP 连接、身份认证、权限缓存(修改权限需重连生效)。
- 查询缓存(8.0 前):相同 SQL 命中缓存;8.0 已移除,不必再依赖。
- 分析器:词法语法解析,报错 Syntax error 出在这里。
- 优化器:选择索引、连接顺序、是否使用 ICP/MRR。
- 执行器:调用存储引擎接口,逐行或索引范围读取。
- 存储引擎:InnoDB 负责缓冲池、锁、MVCC 与日志。
查询 vs 更新
SELECT 可走只读快照;UPDATE/DELETE 需加锁并写 undo/redo。同一连接内语句顺序影响锁持有时间。
实践建议
1 | EXPLAIN FORMAT=TREE SELECT * FROM orders WHERE user_id = 1 AND status = 'PAID'; |
用 profiling/performance_schema 看阶段耗时,区分解析慢还是引擎 IO 慢。
Prepared Statement
预编译减少解析开销,防 SQL 注入。注意 max_prepared_stmt_count。ORM 默认 prepared 与连接池复用要匹配。
权限与 definer
视图/存储过程 DEFINER 影响执行权限边界;SECURITY INVOKER 更安全。
实践复习清单
能手绘连接器到引擎链路;区分解析错误与优化错误;会用 EXPLAIN ANALYZE;理解 prepared statement 与连接池;知道权限变更需重连;8.0 不再依赖 query cache。
常见坑
- 以为「有索引就一定走索引」,优化器可能选全表扫。
- 长事务占连接不释放,拖垮连接池。
- 在连接器层混用不同 charset 导致后续隐式转换。
总结与自测
连接器、分析器、优化器、执行器各自职责?prepared statement 好处?8.0 为何移除 query cache?权限修改何时生效?用一条 JOIN 更新 SQL 走读全链路,是检验理解的最好方式。
原理延伸
InnoDB 的核心竞争力在于把 B+ 树索引、缓冲池、redo/undo 与 MVCC 组合成可预测的 OLTP 引擎。读路径尽量走缓冲池与覆盖索引,写路径则要在行锁、日志刷盘与复制延迟之间取平衡。排查问题时不要只盯单条 SQL,还要看事务边界、锁等待、buffer pool 命中率与磁盘 fsync 延迟。性能优化永远遵循「先正确、再可测、后优化」:用慢日志和 EXPLAIN 定位瓶颈,用规范设计减少回表与锁竞争,用架构手段(读写分离、缓存、分片)承接流量,而不是在未测量前堆参数。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Dai Wei!
评论

