MySQL 慢查询日志排错:订单查询 Query_time 从 15.2s 到 0.02s
动态开启慢查询日志
动态开启,临时生效:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL long_query_time = 1; -- 1秒以上视为慢查询
SET GLOBAL log_queries_not_using_indexes = 'ON'; -- 记录无索引查询
SET GLOBAL log_slow_admin_statements = 'ON'; -- 记录慢管理语句(如 ALTER)
SET GLOBAL log_slow_slave_statements = 'ON'; -- 从库慢查询也记录
-- min_examined_row_limit = 1000 扫描行数超1000才记录
-- long_query_time 可再设一个 10 秒强制记录阈值
案例:高峰期订单查询超时
电商平台高峰期订单查询接口响应超时(>3 秒),用户投诉量激增。慢查询日志(long_query_time=1 秒)显示某 SQL 的 Query_time 远超阈值。
排查流程
1. 定位慢查询(11:05)
分析慢查询日志:
pt-query-digest /var/log/mysql/slow.log
发现元凶:
SELECT * FROM product WHERE category_id=123 AND status=1 ORDER BY sales DESC LIMIT 100;
-- Query_time: 15.2s, Rows_examined: 500000, Rows_sent: 100
全表扫描,有效数据极少。
2. 优化 SQL 与索引(11:10)
创建联合索引:
CREATE INDEX idx_category_status_sales ON product(category_id, status, sales);
并把 SELECT * 改成只查需要的字段:
SELECT id, name, price, sales FROM product WHERE category_id=...
3. 验证优化效果(11:15)
执行优化后的 SQL,Query_time: 0.02s;CPU 使用率降到 20% 以下;将读流量切回主库。
经验
- 建立慢查询监控,慢查询超 10 条告警。
- ROW 格式 binlog 优先,保证数据一致性。
- 慢查询日志默认按阈值记录;
log_queries_not_using_indexes会带来额外日志量,高并发下慎用。