SQL 慢不等于“磁盘慢”。一次请求会经过客户端连接、MySQL Server 层、优化器、执行器和 InnoDB;先定位耗时在哪一段,调优才不会靠猜。
Table of contents
两层架构
MySQL Server 层处理连接认证、SQL 解析、权限、优化和执行;存储引擎负责表和索引数据的实际读写。MySQL 8.4 默认引擎是 InnoDB,它提供事务、行级锁、崩溃恢复和 MVCC。
应用/连接池
→ 连接与认证
→ 解析器:SQL 是否合法
→ 优化器:选择表顺序、索引和访问方式
→ 执行器:按计划向存储引擎取行
→ InnoDB:Buffer Pool、B+Tree、锁与日志
“优化器”是选择执行计划的组件。同一条 SQL 可能走不同索引,因为统计信息、参数分布和数据量会变化。索引存在不代表一定被选中。
读请求经历什么
连接池借出已认证连接;服务器解析 SQL 并检查权限;优化器估算不同计划成本;执行器按计划请求索引页。目标页若在 Buffer Pool 中就是内存命中,否则触发 I/O。最后经过 JDBC 网络分批返回,并由 MyBatis 映射。
因此端到端慢查询至少要同时看:连接等待、数据库执行时间、扫描/返回行数、网络字节、应用映射和线程排队。
写请求多了哪些步骤
更新需要定位记录并加锁,生成 Undo 以支持回滚和旧版本读取,生成 Redo 以支持崩溃恢复,修改内存页,提交时按配置刷日志,并把复制所需变更写入 Binlog。数据页通常稍后批量刷盘,不是每次提交都直接改数据文件。
动手观察
docker compose up -d --wait
docker compose exec mysql mysql -ulab -plab architecture_lab
实验镜像固定为 MySQL 8.4.12 LTS。可用 EXPLAIN ANALYZE SELECT ...查看实际执行;不要在高负载生产语句上未经评估直接运行,因为它会真的执行查询。
下一步
继续阅读06-05 InnoDB 页、行与 B+Tree 索引,理解为什么一次索引查询常常还要“回表”。