sql优化之如何找到那些慢SQL

 更新时间:2026年05月09日 11:41:35   作者:G探险者  
执行SQL语句时,如果出现慢SQL或SQL占用系统内存的情况,需进行具体查询分析,这篇文章主要介绍了sql优化之如何找到那些慢SQL的相关资料,文中给出了详细的代码示例,需要的朋友可以参考下

适用版本:MySQL 5.7 / 8.0

今天聊一聊sql优化的问题,怎么找到那些慢SQL。

一、什么是慢 SQL?

慢 SQL 是指执行时间超过预设阈值的 SQL 语句。在 MySQL 中,这个阈值由参数 long_query_time 控制,默认值为 10 秒,实际生产环境中通常设置为 1~2 秒。

慢 SQL 是数据库性能问题最常见的根源,主要表现为:

  • 页面响应缓慢,接口超时
  • 数据库 CPU 飙高,连接数堆积
  • 锁等待,导致其他业务也受影响

二、开启慢查询日志

要找到慢 SQL,首先需要开启 MySQL 的慢查询日志功能。

2.1 查看当前状态

SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

2.2 临时开启(重启后失效)

-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';

-- 设置阈值:超过 2 秒算慢 SQL
SET GLOBAL long_query_time = 2;

-- 设置日志输出到表(推荐,方便直接查询)
SET GLOBAL log_output = 'TABLE';

2.3 永久生效(修改配置文件)

编辑 MySQL 配置文件 my.cnf(Linux)或 my.ini(Windows):

[mysqld]
slow_query_log = 1
long_query_time = 2
log_output = TABLE
log_queries_not_using_indexes = 1   # 同时记录未使用索引的 SQL

💡 建议log_queries_not_using_indexes = 1 非常有用,即使执行很快但没走索引的 SQL 也会被记录,可以提前发现潜在隐患。

三、方法一:查询 slow_log 表

log_output = TABLE 时,慢 SQL 会写入 mysql.slow_log 表,可以直接用 SQL 查询。

3.1 查询最近的慢 SQL

SELECT
    start_time,
    ROUND(TIME_TO_SEC(query_time), 3) AS 执行秒数,
    ROUND(TIME_TO_SEC(lock_time), 3)  AS 锁等待秒数,
    rows_examined                      AS 扫描行数,
    rows_sent                          AS 返回行数,
    db                                 AS 数据库,
    sql_text                           AS SQL内容
FROM mysql.slow_log
ORDER BY query_time DESC
LIMIT 20;

3.2 按数据库筛选

SELECT * FROM mysql.slow_log
WHERE db = 'your_database'
ORDER BY query_time DESC
LIMIT 20;

四、方法二:performance_schema 分析

performance_schema 是 MySQL 内置的性能数据采集框架,能统计所有 SQL 的累计执行情况,找出高频且耗时的 SQL。

4.1 查询最耗时的 TOP 10 SQL

SELECT
    DIGEST_TEXT                                           AS SQL摘要,
    COUNT_STAR                                            AS 执行次数,
    ROUND(AVG_TIMER_WAIT / 1000000000000, 3)             AS 平均耗时秒,
    ROUND(MAX_TIMER_WAIT / 1000000000000, 3)             AS 最大耗时秒,
    ROUND(SUM_TIMER_WAIT / 1000000000000, 3)             AS 总耗时秒,
    SUM_ROWS_EXAMINED                                     AS 总扫描行数
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;

4.2 通过 sys schema 更简便地查询

sys schema 是对 performance_schema 的封装,SQL 更简洁易读:

-- 查询最耗时的 SQL(按总耗时排序)
SELECT * FROM sys.statement_analysis
ORDER BY total_latency DESC
LIMIT 10;

-- 查询全表扫描最多的 SQL
SELECT * FROM sys.statements_with_full_table_scans
ORDER BY no_index_used_count DESC
LIMIT 10;

五、方法三:工具客户端分析

5.1 MySQL Workbench(推荐)

连接数据库后,在左侧导航找到 Performance 菜单:

  • Performance → Dashboard:实时监控面板,查看 QPS、连接数、缓冲池等
  • Performance → Statement Analysis:列出所有 SQL 及其平均耗时、执行次数
  • Performance → Query Statistics:按类型统计 SELECT/INSERT/UPDATE 的耗时占比

5.2 DBeaver

  • 执行 SQL 后,底部结果面板直接显示执行时间
  • Window → Query Manager:查看历史 SQL 及每条的耗时
  • 选中 SQL → Ctrl+Shift+E:图形化执行计划

5.3 Percona PMM(生产环境推荐)

PMM(Percona Monitoring and Management)是专业的 MySQL 监控平台,适合生产环境:

  • Query Analytics 面板:实时展示所有 SQL 的执行频率和耗时
  • 支持按时间段过滤,定位某次性能抖动期间的慢 SQL
  • 可下钻到单条 SQL 查看执行计划和历史趋势

六、找到慢 SQL 后如何分析

找到慢 SQL 只是第一步,接下来需要通过执行计划(EXPLAIN)分析慢的原因。

6.1 使用 EXPLAIN 分析

EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = 1;

-- MySQL 8.0+ 支持更详细的 EXPLAIN ANALYZE
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 123 AND status = 1;

6.2 关键字段解读

字段关注点说明
type最重要ALL = 全表扫描(差),ref / eq_ref = 走索引(好)
key是否用索引NULL 表示未使用任何索引
rows扫描行数数值越大性能越差
Extra附加信息Using filesort / Using temporary 需要重点优化
filtered过滤比例越低代表从扫描结果中筛选越多,效率越低

6.3 常见慢 SQL 原因

  • 未建索引,或索引建了但没有命中(索引失效)
  • SQL 写法导致索引失效,例如对索引列使用函数、隐式类型转换
  • SELECT * 拉取了不必要的列,返回数据量过大
  • JOIN 关联字段未建索引,产生笛卡尔积
  • 数据量大但没有分页,一次查询百万行数据

七、排查流程总结

步骤操作工具
第一步开启慢查询日志SET GLOBAL slow_query_log='ON'
第二步收集慢 SQL 列表查询 mysql.slow_logsys.statement_analysis
第三步找出最耗时的 SQLquery_time 降序排列,取 TOP 10
第四步分析执行计划EXPLAIN 命令 或 DBeaver / Workbench 图形化
第五步定位慢的原因type / key / rows / Extra 字段
第六步优化处理加索引、改写 SQL、分页、分库分表等

八、常用命令速查

-- 查看慢查询配置
SHOW VARIABLES LIKE 'slow%';

-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';

-- 设置慢查询阈值(秒)
SET GLOBAL long_query_time = 2;

-- 查询慢 SQL 列表
SELECT * FROM mysql.slow_log ORDER BY query_time DESC LIMIT 20;

-- 查 TOP 10 耗时 SQL
SELECT * FROM sys.statement_analysis LIMIT 10;

-- 查全表扫描的 SQL
SELECT * FROM sys.statements_with_full_table_scans LIMIT 10;

-- 分析执行计划
EXPLAIN SELECT ...;

-- 详细执行计划(MySQL 8.0+)
EXPLAIN ANALYZE SELECT ...;

-- 清空慢日志表
TRUNCATE TABLE mysql.slow_log;

小结:慢 SQL 排查的核心思路是「先发现、再定位、后优化」。建议在测试和生产环境都长期开启慢查询日志,并定期检查 sys.statement_analysis,做到防患于未然。

总结 

到此这篇关于sql优化之如何找到那些慢SQL的文章就介绍到这了,更多相关慢SQL查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解MySQL查看执行慢的SQL语句(慢查询)

    详解MySQL查看执行慢的SQL语句(慢查询)

    查看执行慢的SQL语句,需要先开启慢查询日志,MySQL的慢查询日志,记录在MySQL中响应时间超过阀值的语句(具体指运行时间超过long_query_time值的SQL,本文给大家介绍MySQL查看执行慢的SQL语句,感兴趣的朋友跟随小编一起看看吧
    2024-03-03
  • ‌MySQL中‌between and的基本用法‌操作方法

    ‌MySQL中‌between and的基本用法‌操作方法

    本文主要介绍了MySQL中BETWEEN AND操作符的基本用法,包括数值查询和时间范围查询,同时还详细解释了NOT BETWEEN AND的使用方法,并通过实例进行了详细的演示,其中,BETWEEN AND可以用于数值、日期等类型的字段,包括边界值
    2024-10-10
  • 解决Mysql建表时报错invalid ON UPDATE clause for 'create_date' column

    解决Mysql建表时报错invalid ON UPDATE clause for 'create_d

    这篇文章主要介绍了解决Mysql建表时报错invalid ON UPDATE clause for 'create_date' column问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • SQL多表联查的几种方法示例总结

    SQL多表联查的几种方法示例总结

    本文详细介绍了SQL中不同类型的连接操作,包括内连接、左外连接、右外连接、全外连接、交叉连接、自连接及其排除内连接的特殊应用,每种连接类型都提供了语法说明和具体示例,帮助理解如何在实际中应用这些连接来处理和分析数据,需要的朋友可以参考下
    2024-09-09
  • MySQL 字符串截取函数及用法详解

    MySQL 字符串截取函数及用法详解

    在MySQL中,字符串截取是常见的操作,主要用于从字符串中提取特定部分,MySQL 提供了多种函数来实现这一功能,包括 LEFT()、RIGHT()、SUBSTRING()、MID()、SUBSTR() 和 SUBSTRING_INDEX() 等,本文将详细介绍这些函数的用法,并通过示例进行说明,需要的朋友可以参考下
    2025-05-05
  • MySQL中的索引创建及应用

    MySQL中的索引创建及应用

    文章介绍了MySQL中索引的概念、用途、弊端、应用场景以及创建、删除索引的方法,还详细讲解了索引的分类,包括逻辑应用维度、物理存储维度和数据存储结构维度,最后,文章还分析了MySQL中索引的存储结构,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2026-01-01
  • MySQL、Oracle与SQLServer三大数据库语法全方位区别分析

    MySQL、Oracle与SQLServer三大数据库语法全方位区别分析

    不同的数据库产品在语法上略有不同,这篇文章主要介绍了MySQL、Oracle与SQLServer三大数据库语法全方位区别分析的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-03-03
  • 修改MySQL密码的四种方法总结(适合初学者!)

    修改MySQL密码的四种方法总结(适合初学者!)

    在日常使用数据库的过程中,难免会遇到需要修改账号密码的情景,比如密码太简单需要修改、密码过期需要修改、忘记密码需要修改等,下面这篇文章主要给大家介绍了关于修改MySQL密码的四种方法,介绍的方法非常适合初学者,需要的朋友可以参考下
    2022-08-08
  • 浅谈mysql通配符进行模糊查询的实现方法

    浅谈mysql通配符进行模糊查询的实现方法

    这篇文章主要介绍了浅谈mysql通配符进行模糊查询,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • MySQL CHECK约束(5.7和8.0)的使用

    MySQL CHECK约束(5.7和8.0)的使用

    CHECK约束用于确保数据表中的某列或多列的数据符合特定的条件,本文主要介绍了MySQL CHECK约束(5.7和8.0)的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08

最新评论