开启慢查询日志 → 抓取慢 sql → 分析 sql 执行计划 → 优化 sql / 索引。
首先开发mysql 慢查询
登录 mysql 查看当前状态
-- 查看慢查询日志整体开关 show variables like 'slow_query_log'; -- 查看慢查询阈值(默认 10秒) show variables like 'long_query_time'; -- 查看慢日志文件存放路径 show variables like 'slow_query_log_file';
临时开启(重启失效,适合临时排查)
-- 1. 开启慢查询日志 set global slow_query_log = on; -- 2. 设置阈值:执行超过 1秒 就记录 set global long_query_time = 1; -- 3. 可选:记录没有走索引的sql set global log_queries_not_using_indexes = on;
注意:global 修改后,新连接才生效,当前会话需要重连。
永久开启(my.cnf/my.ini,生产推荐)
1. 找到配置文件
- linux:
/etc/my.cnf或/etc/mysql/my.cnf - windows:
my.ini
2. 在 [mysqld] 模块添加
[mysqld] # 开启慢查询日志 slow_query_log = 1 # 慢日志文件路径 slow_query_log_file = /var/log/mysql/slow.log # 慢查询时间阈值 1s long_query_time = 1 # 记录未使用索引的sql log_queries_not_using_indexes = 1 # 避免日志刷爆,限制每分钟记录条数 log_throttle_queries_not_using_indexes = 10
3. 重启 mysql 生效
# centos systemctl restart mysqld # ubuntu systemctl restart mysql
long_query_time:包含锁等待时间,不只是 sql 执行时间- 慢日志会损耗少量 io,生产不要开太大阈值,一般设 1s
- 大流量环境不要开启
log_queries_not_using_indexes,容易日志爆炸
查看慢查询日志
直接看日志文件
# 查看最后100行慢查询 tail -n 100 /var/lib/mysql/localhost-slow.log
日志里会记录:
- 执行时间
- 锁等待时间
- 扫描行数
- 具体 sql 语句
mysqldumpslow(mysql 自带)
# 查看耗时最多的10条慢sql mysqldumpslow -s t -t 10 /var/log/mysql/slow.log # 按访问次数排序 mysqldumpslow -s c -t 10 慢日志路径
专业工具
pt-query-digest(percona 工具集,线上分析首选)- 配合监控:prometheus + grafana、阿里云 / 云数据库自带慢查询分析
分析慢 sql
抓到慢 sql 后,用 explain 看执行计划,判断问题在哪。
-- `explain` 是 mysql 提供的**诊断命令**, explain select * from orders where user_id = 1001 and create_time > '2025-01-01';
type:最重要
all:全表扫描(最差,必须优化)index:索引全扫描range:范围索引(正常)ref/eq_ref:精准索引(优秀)
key:实际使用的索引
- 为
null= 没用到索引
rows:扫描的行数
- 越大越慢
常见慢查询原因 & 解决方案
没有索引 / 索引失效(80% 场景): where、join、order by 字段没建索引
-- 给 user_id + create_time 建【联合索引】 create index idx_user_id_create_time on orders(user_id, create_time);
索引失效的典型写法
-- 会导致索引失效 不能对【索引列】做任何函数运算、四则运算、隐式转换、后置模糊匹配 select * from t where year(create_time) = 2025; select * from t where id + 1 = 100; select * from t where name like '%张三';
改成:
select * from t where create_time >= '2025-01-01' and create_time < '2026-01-01'; select * from t where id = 99; select * from t where name like '张三%';
一次性查询太多数据
select * from big_table; -- 无where条件,全表扫描
解决:加 limit、分页、分批查询。
锁等待 / 大事务: sql 本身很快,但执行时间很长
-- 查看 innodb 底层实时状态 show engine innodb status;
看事务锁等待信息。
数据库服务器负载高: cpu/io/内存 瓶颈
show processlist; -- 查看正在执行的sql
到此这篇关于mysql慢查询排查与优化指南的文章就介绍到这了,更多相关mysql慢查询排查与优化内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论