MySQL慢查询优化实战案例
请以实际案例讲解MySQL慢查询的排查和优化步骤。如何开启慢查询日志?如何使用mysqldumpslow和pt-query-digest分析慢查询?优化大分页查询(LIMIT offset, size)有哪些技巧?
回答
Yahuda
开启慢查询日志:
-- 查看慢查询配置
SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';
-- 临时开启(生产慎用)
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1; -- 超过1秒为慢查询
SET GLOBAL log_queries_not_using_indexes = ON;
慢查询分析工具:
- mysqldumpslow(MySQL自带)
mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log— 按时间排序取前10 - pt-query-digest(Percona Toolkit)
pt-query-digest /var/lib/mysql/slow.log— 生成详细分析报告
大分页优化案例(LIMIT 100000, 20):
方案1:主键ID覆盖
-- 先用覆盖索引查出ID,再JOIN回完整数据
SELECT * FROM t
INNER JOIN (SELECT id FROM t WHERE ... ORDER BY id LIMIT 100000, 20) AS tmp
ON t.id = tmp.id;
方案2:书签(游标)分页
-- 记住上次最后一条的ID,而不是偏移量
SELECT * FROM t WHERE id > 100000 AND ... ORDER BY id LIMIT 20;
方案3:延迟关联
-- 先取主键ID,再回表
SELECT * FROM t WHERE id IN (
SELECT id FROM t WHERE ... ORDER BY ... LIMIT 100000, 20
);
其他优化:
- 检查索引是否被使用(EXPLAIN type != ALL)
- 避免SELECT *(只取必要字段,利用覆盖索引)
- 大表考虑分区表或归档历史数据