问题描述
生产环境 MySQL 数据库出现大量慢查询,导致应用响应时间变长。
环境信息
- MySQL 8.0
- InnoDB 存储引擎
- 数据量:约 1000 万条记录
- 硬件:8核 CPU,32GB 内存
慢查询分析
1. 启用慢查询日志
-- 查看当前配置
SHOW VARIABLES LIKE 'slow_query_log%';
SHOW VARIABLES LIKE 'long_query_time';
-- 启用慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- 2秒
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
2. 分析慢查询日志
# 使用 mysqldumpslow 分析
mysqldumpslow -s t /var/log/mysql/slow.log
# 使用 pt-query-digest 分析
pt-query-digest /var/log/mysql/slow.log
常见慢查询问题
1. 缺少索引
-- 问题查询
SELECT * FROM orders
WHERE user_id = 123
AND status = 'completed'
AND created_at > '2026-01-01';
-- 解决方案:添加复合索引
CREATE INDEX idx_user_status_date ON orders(user_id, status, created_at);
2. 索引失效
-- 问题:使用函数导致索引失效
SELECT * FROM users
WHERE DATE(created_at) = '2026-03-19';
-- 解决方案:避免在列上使用函数
SELECT * FROM users
WHERE created_at >= '2026-03-19'
AND created_at < '2026-03-20';
3. 全表扫描
-- 问题:OR 条件导致全表扫描
SELECT * FROM products
WHERE category_id = 1
OR price > 1000;
-- 解决方案:使用 UNION
SELECT * FROM products WHERE category_id = 1
UNION
SELECT * FROM products WHERE price > 1000;
优化方案
方案一:索引优化
-- 分析索引使用情况
EXPLAIN SELECT * FROM orders WHERE user_id = 123;
-- 创建合适的索引
CREATE INDEX idx_user_id ON orders(user_id);
CREATE INDEX idx_created_at ON orders(created_at);
-- 删除无用索引
DROP INDEX idx_unused ON orders;
方案二:查询重写
-- 优化前:子查询
SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders WHERE amount > 1000);
-- 优化后:JOIN 查询
SELECT u.* FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.amount > 1000;
方案三:分页优化
-- 优化前:OFFSET 分页
SELECT * FROM orders
ORDER BY id
LIMIT 1000 OFFSET 100000; -- 性能差
-- 优化后:游标分页
SELECT * FROM orders
WHERE id > 100000
ORDER BY id
LIMIT 1000;
性能监控
1. 实时监控
-- 查看当前连接和查询
SHOW PROCESSLIST;
-- 查看锁信息
SHOW ENGINE INNODB STATUS;
-- 查看索引统计
SHOW INDEX FROM orders;
2. 性能指标
-- 查询缓存命中率
SHOW STATUS LIKE 'Qcache%';
-- InnoDB 缓冲池命中率
SHOW STATUS LIKE 'Innodb_buffer_pool%';
-- 表扫描率
SHOW STATUS LIKE 'Handler_read%';
预防措施
- 定期分析慢查询日志
- 实施 SQL 审核流程
- 使用查询缓存和连接池
- 定期优化表和索引
- 监控数据库性能指标
相关工具
- Percona Toolkit
- MySQLTuner
- pt-query-digest
- EXPLAIN ANALYZE(MySQL 8.0+)
🏷️ 关键词:
MySQL
慢查询
性能优化
索引
SQL优化