MySQL 慢查询排查的实现

 更新时间:2026年07月29日 09:06:13   作者:长大1988  
本文主要介绍了MySQL 慢查询排查的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

这是一套可直接上手的排查方案,从发现问题到定位根因,再到优化落地,覆盖全链路。

第一步:确认慢查询是否存在

1.1 开启慢查询日志

-- 查看当前状态
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;

1.2 查看慢查询数量与内容

# 统计慢查询次数
SHOW GLOBAL STATUS LIKE '%Slow_queries%';

# 查看最近慢查询日志文件路径
SHOW VARIABLES LIKE 'slow_query_log_file';

第二步:分析慢查询语句

2.1 使用 EXPLAIN 分析执行计划

EXPLAIN SELECT * FROM orders WHERE status = 1 ORDER BY created_at DESC LIMIT 100;

重点关注字段:

字段危险信号
typeALL(全表扫描)、index(索引全扫)
rows远大于预期返回行数
ExtraUsing filesort(文件排序)、Using temporary(临时表)

2.2 使用 SHOW PROFILE 查看耗时分布

-- 开启 profiling
SET profiling = 1;

-- 执行你的慢查询
SELECT * FROM orders WHERE ...;

-- 查看所有查询的耗时
SHOW PROFILES;

-- 查看具体某个 Query_ID 的详细耗时
SHOW PROFILE FOR QUERY 1;

关键看 Sending data、Sorting result、Creating tmp table 等步骤的耗时占比。

第三步:常见原因与对应解决方案

3.1 没走索引 → 加索引

-- 检查是否有可用索引
SHOW INDEX FROM orders;

-- 添加复合索引(注意字段顺序:等值条件在前,范围条件在后)
ALTER TABLE orders ADD INDEX idx_status_created (status, created_at);

3.2 索引失效 → 改写 SQL

常见导致索引失效的操作:

  • 对索引列使用函数:WHERE DATE(created_at) = '2024-01-01'
  • 隐式类型转换:WHERE user_id = '123'(user_id 是 int)
  • 前导模糊匹配:WHERE name LIKE '%张三'

3.3 数据量过大 → 分页优化 / 归档

深分页优化示例

-- 原始写法(越往后越慢)
SELECT * FROM orders ORDER BY id LIMIT 100000, 20;

-- 优化写法(子查询用覆盖索引)
SELECT * FROM orders 
WHERE id > (SELECT id FROM orders ORDER BY id LIMIT 100000, 1)
ORDER BY id LIMIT 20;

数据归档: ​ 将历史数据迁移到归档表或分区表。

3.4 锁等待 → 排查锁冲突

-- 查看当前正在等待锁的事务
SELECT * FROM information_schema.INNODB_TRX\G

-- 查看锁等待关系
SELECT * FROM sys.schema_table_lock_waits;

-- 强制结束阻塞事务(慎用)
KILL [trx_mysql_thread_id];

3.5 SQL 写得烂 → 重写

典型坏写法:

  • SELECT * → 只取需要的列
  • 子查询嵌套过深 → 改用 JOIN 或临时表
  • OR 条件 → 拆成 UNION ALL
  • 循环查询 → 批量查询 + IN

第四步:系统层面排查

4.1 查看数据库配置是否合理

-- 关键参数检查
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';    -- 建议设为内存的60%-70%
SHOW VARIABLES LIKE 'tmp_table_size';              -- 临时表大小限制
SHOW VARIABLES LIKE 'max_connections';             -- 连接数是否过高

4.2 查看服务器资源

# CPU、内存、IO 情况
top
iostat -x 1
free -h

如果 CPU 高但 IO 低 → SQL 计算量大或索引不合理

如果 IO 高但 CPU 低 → 磁盘瓶颈,考虑 SSD 或增加 buffer pool

第五步:建立长效机制

5.1 定期巡检脚本

-- 查询当前运行时间最长的SQL
SELECT * FROM information_schema.PROCESSLIST 
WHERE COMMAND != 'Sleep'
ORDER BY TIME DESC LIMIT 10;

-- 查询全表扫描次数最多的表
SELECT * FROM sys.schema_unused_indexes;

5.2 监控告警

  • 设置 long_query_time = 1,持续采集慢查询日志
  • 使用 Percona Toolkit 的 pt-query-digest 分析日志规律
  • 接入 Prometheus + Grafana 监控 QPS、慢查询数量趋势

一句话总结排查思路

先确认慢在哪(日志+profile),再看为什么慢(explain+索引),最后对症下药(加索引/改SQL/扩资源)。

到此这篇关于MySQL 慢查询排查的实现的文章就介绍到这了,更多相关MySQL 慢查询排查内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL间隙锁解决幻读问题

    MySQL间隙锁解决幻读问题

    本文主要介绍了MySQL间隙锁解决幻读问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • MySQL同步ES的主流方案汇总

    MySQL同步ES的主流方案汇总

    在日常开发中,我们经常遇到这样的场景:MySQL作为核心数据库存储业务数据,而Elasticsearch(ES)则承担着全文检索和数据分析的重任,如何让MySQL和ES保持数据一致性,成了每个后端工程师都绕不开的问题,所以本文给大家介绍了MySQL同步ES的5种主流方案
    2026-03-03
  • MySQL数据库健康检查从脚本到全面巡检的完整方案

    MySQL数据库健康检查从脚本到全面巡检的完整方案

    在数据库运维工作中,定期对MySQL数据库进行健康检查是保证系统稳定运行的重要环节,一个完善的数据库巡检方案可以帮助DBA及时发现潜在问题,优化性能,预防故障发生,本文将基于多个优秀的MySQL巡检脚本实现,整理出一套完整的MySQL健康检查方案,需要的朋友可以参考下
    2025-11-11
  • MySQL连接控制插件介绍

    MySQL连接控制插件介绍

    当连接数据库失败次数过多时,MySQL 是否会限制登录呢?数据库服务端应该怎么应对暴力破解呢?本篇文章介绍下 MySQL 中的连接控制插件,一起来学习下此插件的作用,需要的朋友可以参考下面文章内容
    2021-09-09
  • mysql正确安全清空在线慢查询日志slow log的流程分享

    mysql正确安全清空在线慢查询日志slow log的流程分享

    这篇文章主要介绍了正确安全清空在线慢查询日志slow log的流程,需要的朋友可以参考下
    2014-02-02
  • MySQL线程处于Opening tables的问题解决方法

    MySQL线程处于Opening tables的问题解决方法

    在本篇文章里小编给大家分享了关于MySQL线程处于Opening tables的问题解决方法,有兴趣的朋友们学习下。
    2019-01-01
  • MySQL 复制表的方法

    MySQL 复制表的方法

    这篇文章主要介绍了MySQL 复制表的方法,帮助大家更好的理解和学习使用MySQL,感兴趣的朋友可以了解下
    2021-03-03
  • 如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

    如何解决mysql出现Incorrect string value for co

    这篇文章主要介绍了如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • Mysql错误1366 - Incorrect integer value解决方法

    Mysql错误1366 - Incorrect integer value解决方法

    这篇文章主要介绍了Mysql错误1366 - Incorrect integer value解决方法,本文通过修改字段默认值解决,需要的朋友可以参考下
    2014-09-09
  • MySQL事务的SavePoint简介及操作

    MySQL事务的SavePoint简介及操作

    SavePoint是数据库事务中的一个概念, 可以将整个事务切割为不同的小事务, 可以选择将状态回滚到某个小事务发生时的样子,本文给大家分享MySQL事务的SavePoint重要操作,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-01-01

最新评论