文章目录
-
- [1. 开启/检查慢日志](#1. 开启/检查慢日志)
- [2. 分析日志](#2. 分析日志)
- [3. 用explain分析执行计划](#3. 用explain分析执行计划)
-
- [1. `type` ⭐⭐⭐(**最关键字段!**)](#1.
type⭐⭐⭐(最关键字段!)) - [2. `rows` ⭐](#2.
rows⭐) - [3. `key` ⭐](#3.
key⭐) - [4.`Extra` ⭐⭐⭐(**隐藏陷阱!**)](#4.
Extra⭐⭐⭐(隐藏陷阱!))
- [1. `type` ⭐⭐⭐(**最关键字段!**)](#1.
1. 开启/检查慢日志
- 看一下是否开启慢日志
sql
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
SHOW VARIABLES LIKE 'slow_query_log_file';
- 如果未开启,临时开启(生产环境建议永久配置):
sql
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
2. 分析日志
-
mysqldumpslow(MySQL 自带)
bash# 按执行次数排序前10条 mysqldumpslow -s c -t 10 /var/log/mysql/slow.log # 按总耗时排序前10条 mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
3. 用explain分析执行计划
-
在SQL前面加explain
sqlEXPLAIN SELECT id, order_no FROM orders WHERE user_id = 100 AND create_time >= '2024-01-01' ORDER BY create_time DESC;- 重点查看四个字段
| 字段 | 看什么 |
|---|---|
| type | 是否出现 ALL(全表扫描) |
| rows | 扫描行数是否过大 |
| key | 是否使用到了正确索引 |
| Extra | 是否出现 Using filesort 或 Using temporary |
1. type ⭐⭐⭐(最关键字段!)
访问效率从高到低:
system > const > eq_ref > ref > range > index > ALL
| 值 | 说明 | 是否理想 |
|---|---|---|
const |
通过主键/唯一索引查一行 (如 WHERE id=1) |
✅ 最优 |
eq_ref |
多表连接时,使用主键或唯一索引关联 | ✅ 优秀 |
ref |
使用非唯一索引等值查询 | ✅ 良好 |
range |
索引范围扫描(如 BETWEEN, IN, >) |
⚠️ 可接受 |
index |
全索引扫描(遍历整个索引树) | ❌ 避免 |
ALL |
全表扫描 | ❌ 必须优化! |
💡 目标:让
type至少达到range,最好ref或更高。
2. rows ⭐
- 含义 :预估需要扫描的行数。
- 原则 :
- 越小越好
- 如果
type=ALL且rows很大 → 性能灾难!
3. key ⭐
- 含义 :实际使用的索引。
- 关键检查 :
- 是否为
NULL?→ 未走索引! - 是否是你期望的索引?→ 可能索引失效(如函数操作、隐式转换)
- 是否为
4.Extra ⭐⭐⭐(隐藏陷阱!)
包含重要性能提示:
| 值 | 问题 | 优化方案 |
|---|---|---|
Using where |
服务层过滤(正常) | --- |
Using index |
覆盖索引(无需回表) | ✅ 理想状态 |
Using index condition |
索引条件下推(ICP,MySQL 5.6+) | ✅ 优化 |
❌ Using filesort |
无法用索引排序,需额外排序 | 为 ORDER BY 字段加索引 |
❌ Using temporary |
创建临时表 (如 GROUP BY 无索引) |
为分组字段加索引 |
Select tables optimized away |
优化器直接返回结果(如 MIN/MAX) |
✅ 极优 |
💥 看到
Using filesort或Using temporary必须优化!