悠悠楠杉
MySQL慢查询日志实战:从诊断到优化的完整指南
一、慢查询日志:数据库的"健康检查仪"
慢查询日志是MySQL内置的性能诊断工具,就像飞机的黑匣子,忠实记录所有执行时间超过阈值的SQL语句。当用户抱怨"系统变卡"时,它往往是定位问题的第一突破口。
1.1 开启慢查询日志
```sql
-- 动态开启(重启失效)
SET GLOBAL slowquerylog = 'ON';
SET GLOBAL longquerytime = 1; -- 阈值设为1秒
SET GLOBAL slowquerylog_file = '/var/log/mysql/mysql-slow.log';
-- 永久生效需修改my.cnf
[mysqld]
slowquerylog = 1
longquerytime = 1
logqueriesnotusingindexes = 1 -- 记录未走索引的查询
```
注意:在生产环境建议将long_query_time
设置为0.5-2秒,初期可设为0.1秒抓取更多语句。
二、慢查询分析实战四步法
2.1 原始日志解读
典型的慢日志条目包含:
```log
Time: 2023-08-20T09:12:43.123456Z
User@Host: appuser[appuser] @ [192.168.1.100]
Querytime: 3.452 Locktime: 0.001 Rowssent: 15 Rowsexamined: 500120
SET timestamp=1692529963;
SELECT * FROM orders WHERE customer_id = 100 AND status = 'pending';
```
关键字段解析:
- Query_time
:实际执行时间(秒)
- Rows_examined
:扫描的行数
- Rows_sent
:返回的行数
- Lock_time
:锁等待时间
2.2 使用mysqldumpslow工具
MySQL自带的聚合分析工具:
```bash
统计最慢的10个查询
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
按出现次数排序
mysqldumpslow -s c -t 10 /var/log/mysql/mysql-slow.log
```
2.3 进阶分析利器:pt-query-digest
Percona Toolkit提供的专业工具:
bash
pt-query-digest \
--filter '$event->{arg} =~ m/^SELECT/i' \
/var/log/mysql/mysql-slow.log > slow_report.txt
输出报告包含:
- 查询响应时间占比分布
- 执行频率统计
- 表扫描情况分析
三、高频慢查询优化方案
3.1 索引缺失型优化
案例场景:
sql
SELECT * FROM users WHERE register_date > '2023-01-01';
优化方案:
sql
ALTER TABLE users ADD INDEX idx_register_date (register_date);
经验法则:WHERE条件中的字段、JOIN关联字段、ORDER BY排序字段应优先考虑索引。
3.2 索引失效的常见陷阱
即使有索引也可能失效:
```sql
-- 函数操作导致失效
SELECT * FROM users WHERE DATEFORMAT(createtime,'%Y-%m') = '2023-08';
-- 隐式类型转换
SELECT * FROM products WHERE sku = 100123; -- sku是varchar类型
-- 最左前缀原则
ALTER TABLE users ADD INDEX idxnameage (last_name, age);
SELECT * FROM users WHERE age > 20; -- 无法使用复合索引
```
3.3 分页查询优化
典型慢分页:
sql
SELECT * FROM orders ORDER BY id LIMIT 1000000, 20;
优化方案:
```sql
-- 方案1:使用覆盖索引
SELECT id FROM orders ORDER BY id LIMIT 1000000, 20;
SELECT * FROM orders WHERE id IN (...);
-- 方案2:记住上次位置
SELECT * FROM orders WHERE id > 1000000 ORDER BY id LIMIT 20;
```
3.4 大表JOIN优化
对于多表关联查询:
sql
-- 原始慢查询
SELECT * FROM orders o
JOIN users u ON o.user_id = u.id
WHERE o.create_time > '2023-01-01';
优化策略:
1. 确保关联字段有索引
2. 控制查询时间范围
3. 只查询必要字段
四、预防慢查询的架构设计
- 读写分离:将报表类查询路由到只读副本
- 数据归档:定期将历史数据迁移到归档表
- 缓存策略:对热点数据使用Redis缓存
- SQL审核:上线前用EXPLAIN分析执行计划
通过持续监控慢查询日志,结合上述优化方法,可使MySQL性能提升50%-90%。记住:好的数据库性能不是调出来的,而是设计出来的。
后续建议:每周检查慢查询日志,将优化前后的Querytime和Rowsexamined数据记录下来,形成性能优化看板。
```