54人参与 • 2026-04-01 • MsSqlserver
适用版本:mysql 5.7 / 8.0
今天聊一聊sql优化的问题,怎么找到那些慢sql。
慢 sql 是指执行时间超过预设阈值的 sql 语句。在 mysql 中,这个阈值由参数 long_query_time 控制,默认值为 10 秒,实际生产环境中通常设置为 1~2 秒。
慢 sql 是数据库性能问题最常见的根源,主要表现为:
要找到慢 sql,首先需要开启 mysql 的慢查询日志功能。
show variables like 'slow_query%'; show variables like 'long_query_time';
-- 开启慢查询日志 set global slow_query_log = 'on'; -- 设置阈值:超过 2 秒算慢 sql set global long_query_time = 2; -- 设置日志输出到表(推荐,方便直接查询) set global log_output = 'table';
编辑 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 也会被记录,可以提前发现潜在隐患。
当 log_output = table 时,慢 sql 会写入 mysql.slow_log 表,可以直接用 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;
select * from mysql.slow_log where db = 'your_database' order by query_time desc limit 20;
performance_schema 是 mysql 内置的性能数据采集框架,能统计所有 sql 的累计执行情况,找出高频且耗时的 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;
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;
连接数据库后,在左侧导航找到 performance 菜单:
ctrl+shift+e:图形化执行计划pmm(percona monitoring and management)是专业的 mysql 监控平台,适合生产环境:
找到慢 sql 只是第一步,接下来需要通过执行计划(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;
| 字段 | 关注点 | 说明 |
|---|---|---|
| type | 最重要 | all = 全表扫描(差),ref / eq_ref = 走索引(好) |
| key | 是否用索引 | null 表示未使用任何索引 |
| rows | 扫描行数 | 数值越大性能越差 |
| extra | 附加信息 | using filesort / using temporary 需要重点优化 |
| filtered | 过滤比例 | 越低代表从扫描结果中筛选越多,效率越低 |
select * 拉取了不必要的列,返回数据量过大| 步骤 | 操作 | 工具 |
|---|---|---|
| 第一步 | 开启慢查询日志 | set global slow_query_log='on' |
| 第二步 | 收集慢 sql 列表 | 查询 mysql.slow_log 或 sys.statement_analysis |
| 第三步 | 找出最耗时的 sql | 按 query_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查询方法内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论