🍀 前言
如果你发现自己新写或者重写的接口查询速度变慢,你怎么定位原因呢?可以用explain分析我们的SQL原生代码,又或者可以考虑使用MySQL慢查询日志。这篇文章主要讲述什么是慢查询日志以及开发中可能用到的场景。
但是,现实开发环境中的查询缓慢问题,绝不仅局限于此,往往需要先定位是整个系统的查询变慢了,还是某个功能的问题。这里仅介绍一种排查方式,但好的排查就像侦探破案,要收集证据、合理推理、验证假设,涉及到更多的维度和方面。我先暂在此记录其中一种,后面再加以完善补充。
🌟 慢查询日志是什么?
想象你是一家餐厅的经理,慢查询日志就像是餐厅的"顾客投诉记录本"——专门记录那些上菜特别慢的订单(SQL查询)。当某个查询执行时间超过你设定的"忍耐阈值"(比如2秒),MySQL就会把这个查询的详细信息记录下来。
🏷️ 与EXPLAIN的区别
EXPLAIN就像是"提前看菜谱"——在查询执行前分析它可能怎么运行。而慢查询日志是"事后查监控"——等查询真的变慢了才记录下来。
🍳 实际场景案例
假设我们有一个电商网站的orders
订单表(50万条数据)和users
用户表(10万条数据):
-- 结构简化为:
CREATE TABLE users (id INT PRIMARY KEY,name VARCHAR(100),email VARCHAR(100)
);CREATE TABLE orders (id INT PRIMARY KEY,user_id INT,amount DECIMAL(10,2),create_time DATETIME
);
场景1:发现突然变慢的页面
某天客服反馈"用户订单列表页面加载特别慢",但你不知道具体是哪条SQL导致的。
使用慢查询日志:
- 开启日志(临时设置):
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; -- 记录超过1秒的查询
- 让客服重现问题
- 查看日志发现:
原来是没有给# Query_time: 3.45 Lock_time: 0.00 Rows_sent: 10 Rows_examined: 500000 SELECT * FROM orders WHERE user_id = 1000 ORDER BY create_time DESC;
user_id
加索引导致全表扫描!
场景2:定期健康检查
每周一早上系统总是变慢,怀疑是定时任务导致的。
使用慢查询日志:
- 用工具分析上周日志:
mysqldumpslow -s t /var/log/mysql-slow.log
- 发现每周一6:00都有这样的慢查询:
原来是周报统计查询没有优化!# Query_time: 8.12 Rows_examined: 1200000 SELECT u.name, COUNT(o.id) FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id;
🔧 使用方法四步走
-
开启日志(临时或永久)
-- 临时开启(重启失效) SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; -- 1秒阈值-- 永久开启(修改my.cnf) [mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql-slow.log long_query_time = 1
-
重现问题
- 让用户操作慢的页面
- 或者等待定时任务执行
-
查看日志位置
SHOW VARIABLES LIKE 'slow_query_log_file';
-
分析日志
# 查看最慢的3个查询 mysqldumpslow -t 3 /var/log/mysql-slow.log# 查看所有包含'orders'的慢查询 mysqldumpslow -g 'orders' /var/log/mysql-slow.log
🛠️ 真实优化案例
日志记录:
# Query_time: 5.67 Rows_examined: 500000
SELECT * FROM products
WHERE name LIKE '%手机%'
AND price BETWEEN 1000 AND 2000
ORDER BY sales DESC;
优化步骤:
- 发现没有使用索引(Rows_examined=全表)
- 添加合适索引:
ALTER TABLE products ADD INDEX idx_search (price, sales);
- 改写查询:
SELECT * FROM products WHERE price BETWEEN 1000 AND 2000 AND name LIKE '%手机%' ORDER BY sales DESC;
- 优化后:Query_time降到0.15秒
💡 什么时候该用它?
- 当系统整体变慢,但不确定原因时
- 当特定页面/功能突然变慢时
- 定期检查系统性能时(比如每周分析一次)
- 上线新功能后监控SQL性能时
小结:慢查询日志就像数据库的"体检报告",定期检查才能保持系统健康!
可参考链接🔗:MySQL慢查询日志总结