MySQL 调优实战案例¶
一、发现问题¶
慢查询日志开启:
用 pt-query-digest 分析慢日志,找到 Top SQL。
二、案例:订单列表查询慢¶
现象¶
数据量 1000 万,执行 3 秒。
EXPLAIN 分析¶
关键看:
| 列 | 含义 | 关注 |
|---|---|---|
| type | 访问类型 | 至少 range,最好 ref / const |
| key | 实际用的索引 | NULL 表示没用索引 |
| rows | 预估扫描行数 | 越小越好 |
| Extra | 额外信息 | Using filesort / Using temporary 要警惕 |
本例结果:
全表扫描 + filesort。
三、优化过程¶
1. 加联合索引¶
按 WHERE 等值条件在前,排序字段在后。
2. 再 EXPLAIN¶
走索引,扫描 200 行,filesort 消失。执行时间从 3s → 20ms。
3. 避免 SELECT *¶
只查需要的列:
避免回表(覆盖索引)。
四、其他常见调优点¶
1. 深分页优化¶
-- 慢:LIMIT 1000000, 20
SELECT * FROM t_order ORDER BY id LIMIT 1000000, 20;
-- 快:子查询先定位 id
SELECT * FROM t_order
WHERE id >= (SELECT id FROM t_order ORDER BY id LIMIT 1000000, 1)
ORDER BY id LIMIT 20;
2. 避免索引失效¶
WHERE age + 1 = 10→WHERE age = 9WHERE DATE(create_time) = '2024-01-01'→WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02'LIKE '%abc'无法走普通索引。
3. join 字段类型一致¶
a.uid = b.uid,两边类型不一致会导致索引失效。
五、调优方法论¶
- 抓慢 SQL:慢查询日志 / 监控。
- EXPLAIN:看 type、key、rows、Extra。
- 加索引:WHERE、ORDER BY、GROUP BY、JOIN 字段。
- 改写 SQL:避免函数、避免 SELECT *、深分页优化。
- 验证:EXPLAIN + 实测执行时间。
- 复盘:记录到知识库。
高频追问
- 什么是覆盖索引?索引包含查询所需所有列,不需要回表。
- 什么是回表?二级索引查到主键,再去聚簇索引取完整行。
- 索引不是越多越好:写操作要维护索引,占空间。