适用读者:会写 SQL 但说不清"慢在哪一层"的人。本系列第一篇。
前置:S08 ✅(MyBatis 访问层)。
实测环境:MySQL 8.0.46(Ubuntu 24.04),临时库s11lab(2026-11-05)。
覆盖旧文:2407(326) 2592(389) 1730(116) 1896(111) 2599(16) + 安装组 7 张(373) = 1,273 点。
覆盖扩展:E-S11-001(执行四层)、E-S11-002(Server vs 引擎)、E-S11-010(连接与会话)。
下一篇:S11-B02 · 建表:类型、字符集与范式。
1. 一句话结论
一条 SQL 要过四层:连接层(认证/线程)→ 解析器(语法/词法)→ 优化器(选索引/join 顺序)→ 执行器(调引擎接口)。慢,一定慢在这四层中的某一层。
客户端 → 连接层 → [解析 → 预处理 → 优化器] → 执行器 → 存储引擎(InnoDB)
↑ Server 层 ↑ 引擎层
| 层 | 负责 | 慢的表现 |
|---|---|---|
| 连接层 | 认证、线程复用 | 连接数打满 / 建连慢 |
| 解析/优化 | 生成执行计划 | 选错索引 |
| 执行器 | 按计划调引擎 | 回表多、扫描行数多 |
| 引擎 | 读写数据页、锁、事务 | IO 等待、锁等待 |
2. 四层各自的问题(E-S11-001)
| 层 | 典型故障 | 怎么查 |
|---|---|---|
| 连接 | Too many connections |
show status like 'Threads_connected' |
| 解析/优化 | 走错索引 | EXPLAIN(J03) |
| 执行 | 扫描行数远大于返回行数 | EXPLAIN 的 rows 与 filtered |
| 引擎 | 锁等待、刷脏页 | innodb_lock_waits、innodb_buffer_pool 命中率 |
判据:"这条 SQL 是"算得多"还是"读得多"?" 算得多 → 优化器/计划;读得多 → 索引/回表。
3. Server 层与引擎层的分工(E-S11-002)
| 层 | 有什么 | 换引擎会变吗 |
|---|---|---|
| Server 层 | 连接、解析、优化、执行器、binlog | 不变 |
| 引擎层 | 数据页、索引(B+ 树)、事务、redo/undo | 变 |
这条分层解释了两件事:
binlog属于 Server 层,所以任何引擎都能用它做恢复/同步(J05、A03)。- 索引结构由引擎决定——MyISAM 与 InnoDB 的索引组织方式不同(B05、A01)。
4. 实测:先看清楚"扫了多少行"
create table t_user(id bigint primary key auto_increment, name varchar(64), age int,
city varchar(32), created_at datetime, key idx_age(age)) engine=InnoDB;
-- 灌入 20,000 行(name=u1..u20000, age=n%80)
explain select id,name from t_user where age=30;
实测输出:
type: ref
key: idx_age
key_len: 5
rows: 250
Extra: NULL
读法:type=ref 表示走等值索引;rows=250 是预估扫描行数(20,000 行里 age=30 约 250 条,因为 n%80)。
对比 §J02 的失效案例:where age+1=31 会变成 type=ALL, rows=20000——同一个条件,写法不同,扫描行数差 80 倍。
5. 安装与连接(旧文 7 张卡的归宿)
| 主题 | 要点 |
|---|---|
| 安装(Windows/macOS/Linux) | 版本对齐、字符集 utf8mb4 |
| 启动/连接 | mysql -h -P -u -p;socket vs TCP |
| 库/表操作 | create database / use / show tables |
| 常见问题 | 端口占用、权限、时区 |
这些属于"环境层",与本系列的机制无关——所以只做一张对照表,不展开(详见 S01-B01 的安装方法论)。
6. 五个误区
| 误区 | 真相 |
|---|---|
| "SQL 慢就是数据库不行" | 先看是连接、计划、执行还是引擎 |
| "加机器能解决慢查询" | 选错索引时加机器只分担不解决 |
"rows 是精确值" |
是估算(基于统计信息) |
| "binlog 是引擎日志" | 属于 Server 层 |
| "换引擎不影响 SQL" | 索引结构与锁行为都会变 |
7. 自检
- 一条 SQL 经过哪四层?各层典型故障是什么?
- Server 层与引擎层分别包含什么?
binlog属于哪层? rows是精确值还是估算?- "算得多"与"读得多"分别该查什么?
- 为什么换引擎会影响索引行为?
8. 下一篇
S11-B02 · 建表:数据类型、字符集与范式
执行流程讲完,下一篇从"表怎么设计"开始:char 与 varchar 的真实差别、字符集与排序规则、以及范式与反范式。
本篇属于系列《S11 · 数据库与 SQL》。旧文来源:A-2407/2592/1730/1896/2599 + 安装组 7 张;扩展点 E-S11-001/002/010。EXPLAIN 输出为 MySQL 8.0.46 实测。