主从复制与 SQL 优化
mediumMySQL主从复制读写分离慢查询EXPLAIN
主从复制原理
主库 (Master) 从库 (Slave)
│ │
│ 1. 数据变更 → 写 binlog │
│ ──────────────────────────────────▶│ 2. I/O 线程拉取 binlog
│ │ 写入 relay log
│ │ 3. SQL 线程执行 relay log
│ │ 将变更应用到从库
复制延迟
从库的 SQL 线程是单线程回放,主库高并发写入时从库可能跟不上 → 主从延迟。
解决方案:
- 并行复制:MySQL 5.7+ 支持基于组提交的并行回放
- 半同步复制:主库等待至少一个从库确认收到 binlog 才返回提交成功
- 业务层面:关键读走主库
读写分离
应用层
│
├── 写操作 ──▶ 主库
│
└── 读操作 ──▶ 从库 1 / 从库 2 / 从库 3(负载均衡)
注意事项:刚写入的数据立即读取可能从从库读到旧数据(主从延迟)。解决方案:强制走主库、延迟读、半同步复制。
SQL 优化
EXPLAIN 执行计划
EXPLAIN SELECT * FROM users WHERE name = '张三';
| 关键列 | 含义 | 关注点 |
|---|---|---|
| type | 访问类型 | system > const > eq_ref > ref > range > index > ALL(全表扫描) |
| key | 实际使用的索引 | NULL 说明没用索引 |
| rows | 预估扫描行数 | 越小越好 |
| Extra | 额外信息 | Using index(覆盖索引好) / Using filesort(需优化) / Using temporary(需优化) |
慢查询优化步骤
1. 开启慢查询日志 → 找到慢 SQL
2. EXPLAIN 分析 → 查看执行计划
3. 常见优化:
- 添加合适的索引
- 避免 SELECT *(减少回表)
- 避免在索引列上使用函数
- 小表驱动大表(IN vs EXISTS)
- 分页优化(延迟关联)
- 大查询拆分为小查询
分页优化
-- 慢:深度分页 (OFFSET 100万)
SELECT * FROM orders ORDER BY id LIMIT 1000000, 10;
-- 快:延迟关联(先查索引再回表)
SELECT * FROM orders o
INNER JOIN (SELECT id FROM orders ORDER BY id LIMIT 1000000, 10) t
ON o.id = t.id;
生产高频题
MySQL 主从复制的原理?
主库写 binlog → 从库的 I/O 线程拉取 binlog 写入 relay log → 从库的 SQL 线程执行 relay log。
如何优化慢 SQL?
开启慢查询日志定位慢 SQL → EXPLAIN 分析执行计划 → 添加索引、避免全表扫描、避免 SELECT *、优化分页、避免在索引列上使用函数。