数据库的“病历本”——如何用好慢查询日志定位性能瓶颈

本文涉及的产品
PolarSearch,搜索节点 4核8GB
PolarDB Agent Flow,2核4GB
RDS AI 助手,专业版
简介: 本文详解MySQL慢查询日志的开启、配置与分析实战,涵盖`long_query_time`、`log_queries_not_using_indexes`等关键参数,推荐使用`pt-query-digest`精准定位全表扫描、索引失效、隐式转换等典型性能瓶颈,并给出索引优化与系统化调优流程,助DBA从“救火”迈向主动防控。

关键词​:慢查询日志;性能优化;索引;全表扫描;pt-query-digest;MySQL


大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!

你有没有遇到过这种情况:数据库突然变慢,业务方一直催,你打开监控看到CPU飙高,但不知道是哪个SQL惹的祸。这时候,慢查询日志就是你的“病历本”——它记录了所有执行时间超过阈值的SQL,以及它们的执行计划、锁等待、扫描行数等关键信息。用好慢查询日志,是DBA从“被动救火”走向“主动优化”的第一步。

今天就聊聊:慢查询日志怎么开?怎么看?怎么从日志里找到真正的性能瓶颈?

一、慢查询日志是什么?

慢查询日志是MySQL提供的一种记录执行时间超过指定阈值的SQL语句的日志。你可以把它理解成数据库的“病历本”——哪条SQL“生病”了(跑得慢),它就记下来。日志内容包括:执行时间、锁等待时间、扫描行数、返回行数、使用的索引、用户来源等。

二、如何正确开启和配置

慢查询日志默认是关闭的,生产环境建议开启,但要注意性能开销(写入日志本身也会消耗IO)。

核心参数:

  • slow_query_log:是否开启慢查询日志(ON/OFF)
  • slow_query_log_file:日志文件路径
  • long_query_time:慢查询阈值,单位秒,建议设置为0.1-1秒(根据业务调整)
  • log_queries_not_using_indexes:是否记录没有使用索引的查询(强烈建议开启)
  • log_slow_admin_statements:是否记录慢的管理语句(如OPTIMIZE TABLE)

设置示例:

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 0.5;
SET GLOBAL log_queries_not_using_indexes = ON;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

需要注意的是,long_query_time 设置得越小,记录的SQL越多,日志文件膨胀越快。建议先用1秒观察,再逐步降低。另外,log_queries_not_using_indexes 开启后,即使查询很快,只要没走索引也会被记录,这对发现索引缺失非常有帮助。

三、如何分析慢查询日志

最原始的方式是直接用文本编辑器打开慢查询日志文件,但几百MB甚至GB的文件根本看不过来。推荐使用专业工具:

1. mysqldumpslow(MySQL自带)

# 按平均执行时间排序,取前10条
mysqldumpslow -s at -t 10 /var/log/mysql/slow.log

常用排序参数:

  • -s c:按总次数排序
  • -s t:按总时间排序
  • -s at:按平均时间排序
  • -s l:按锁等待时间排序

2. pt-query-digest(Percona Toolkit,推荐)

pt-query-digest /var/log/mysql/slow.log

输出结果非常详细,会按查询指纹聚合,显示每个查询的总执行次数、平均时间、最长时间、扫描行数、返回行数比例等,还会给出优化建议。

3. 如果慢查询日志文件巨大​,可以先用 head -n 1000 截取一部分样本分析,或者用 grep 筛选特定时间段。

4. 可视化工具​:例如金仓数据库自带的KStudio智能诊断模块,可以自动解析慢查询日志,用图表展示高频慢SQL的分布和执行时间趋势,并给出索引推荐。这类工具对于不熟悉命令行的DBA来说比较友好。

四、从日志中能看出哪些问题?

以下是几种典型慢查询日志片段及对应的问题分析:

案例1:全表扫描

# Query_time: 12.5  Lock_time: 0.1  Rows_sent: 10  Rows_examined: 5000000
SELECT * FROM orders WHERE status = 'PENDING';
  • Rows_examined 远超 Rows_sent,说明扫描了大量行才返回少量数据。
  • 大概率 status 列没有索引,或者索引选择性太差(status只有几个值)。
  • 优化方向:给 status 加索引,或者考虑复合索引(status + 其他常用过滤条件)。

案例2:索引失效(隐式类型转换)

# Query_time: 8.2  Rows_examined: 2000000
SELECT * FROM user WHERE mobile = 13800138000;
  • mobile字段定义为VARCHAR,但查询中用了数字常量,导致索引失效。
  • 优化方向:改为 WHERE mobile = '13800138000'(加引号)。

案例3:排序不合理

# Query_time: 15.0  Rows_examined: 1000000
SELECT * FROM product ORDER BY sales DESC LIMIT 10;
  • ORDER BY sales DESC 导致文件排序(filesort),没有使用索引。
  • 优化方向:在sales列上建立索引,或者使用覆盖索引。

案例4:没有使用索引的查询(log_queries_not_using_indexes开启后捕获)

# Query_time: 0.3  Rows_examined: 500000
SELECT id, name FROM category WHERE parent_id = 10;
  • 虽然执行时间不到1秒,但扫描了50万行,是因为没有走索引。
  • 优化方向:给parent_id建立索引。

五、系统化的优化流程

  1. 设置基线​:记录当前慢查询数量和平均响应时间,作为优化前后的对比依据。
  2. 收集样本​:开启慢查询日志,收集一段时间(如1天)的代表性流量。
  3. 分析排序​:用pt-query-digest找出最“昂贵”的SQL(按总时间或平均时间排序)。
  4. 逐个击破​:针对TOP 5-10的慢查询,查看执行计划(EXPLAIN),分析索引使用情况,进行SQL改写或索引调整。
  5. 验证效果​:上线后观察慢查询日志的变化,确认问题是否解决。
  6. 持续监控​:建议将慢查询日志采集到监控系统(如Prometheus + Grafana),设置告警规则(如每分钟慢查询超过10条则报警)。

六、注意事项与误区

  • 不要只看平均时间​:有些SQL执行频率极高,即使每次只花0.01秒,累积起来也可能是大头。pt-query-digest的总时间排序可以帮你看清楚。
  • 日志文件过大的处理​:可以配置日志轮转(如logrotate),定期清理或归档。
  • 不要在MySQL内部长期开启全量慢查询​:建议采样开启(如每天开启1小时),或者使用performance_schema的更精细监控。
  • 慢查询少了不等于优化完成​:还需要看QPS、TPS、锁等待等指标,避免因优化过度导致其他问题。

七、总结

慢查询日志是DBA最基础也最强大的工具之一。它记录了数据库的“健康问题”,是性能优化的起点。用好它,你可以从“救火队员”变成“预防医生”——在业务投诉之前,主动发现并解决性能隐患。配合自动化分析工具,甚至可以建立慢查询的持续监控和告警体系,让数据库的性能问题无所遁形。

小耶在手,SQL 不愁

还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽……我们下次见~

相关文章
|
1月前
|
SQL 关系型数据库 MySQL
一张5000万行的表,加索引从45秒到0.02秒——索引设计你真的会吗
本文实测5000万订单表:无索引查询45秒,加索引后仅0.02秒(提升2250倍)。详解索引原理、建索引时机、联合索引最左前缀、覆盖索引及隐式转换陷阱,干货不啰嗦!
|
2月前
|
SQL 数据库 数据库管理
写完SQL先别跑,这两步能救你一晚
我是小耶,专注踩坑与填坑,今天分享SQL性能关键:数据库执行顺序(FROM→WHERE→…)与人脑思维的错位——切忌先JOIN后过滤!用实例对比,教你“过滤前置”提速技巧。养成自查习惯,SQL轻松快一倍!
|
2月前
|
SQL JSON 关系型数据库
慢SQL排查三板斧:SHOW PROCESSLIST + 慢查询日志 + EXPLAIN 实战
教你三招快速定位CPU 100%元凶:SHOW PROCESSLIST查活跃查询、开启慢日志+mysqldumpslow分析、EXPLAIN深度诊断SQL性能。干货不啰嗦,专治线上急症!
|
26天前
|
SQL 运维 关系型数据库
DBA必备技能:MySQL误删恢复完全指南(全量备份+binlog回放)
本文详解误删数据(如`DELETE FROM orders`)后的紧急恢复三步法:查Binlog→临时库回放→差异导回,并附4条血泪预防措施。不讲段子,只教能救命的操作!
|
2月前
|
SQL 数据库
多表关联查询入门:LEFT JOIN、INNER JOIN一文搞懂|转行学DB第6天
本文通俗易懂地讲解了数据库多表查询的三种JOIN操作:INNER JOIN(内连接)只返回两表匹配的数据,适用于查询交集数据;LEFT JOIN(左连接)保留左表所有记录并匹配右表数据,适用于查询主表完整信息;RIGHT JOIN(右连接)则保留右表所有记录。
|
2月前
|
SQL 关系型数据库 MySQL
主键、外键和约束:让数据库“有规矩”才能不出错!|转行学DB第5天
本文用通俗易懂的语言讲解了主键(数据的唯一标识)、外键(表间关联)以及唯一约束、非空约束等其他常见约束规则。通过具体SQL示例展示了各种约束的使用方法,并分享了新手容易踩的坑和实用建议。
|
2月前
|
SQL 人工智能 安全
AI圈开始“养马”了?聊聊龙虾退位、爱马仕登基
AI智能体“龙虾”(OpenClaw)的衰落与“爱马仕”(Hermes Agent)的崛起:前者因API限策与高危漏洞(CVSS 9.9)式微;后者以持久记忆、技能自生成、跨平台互通等实用能力破圈,成技术圈新“拐杖”。但技术无银弹,懂你的工具才是真助力。
|
11天前
|
SQL 存储 关系型数据库
覆盖索引:让你的查询直接从索引返回,彻底告别回表
覆盖索引是SQL优化中性价比较高的技巧,让查询直接从索引返回所需列,避免回表操作。本文解释覆盖索引的原理,通过EXPLAIN的“Using index”判断是否生效。结合复合索引设计、深分页优化(延迟关联)等场景,给出覆盖索引的使用方法和注意事项。用好覆盖索引,不改SQL逻辑,仅调整索引设计即可显著提升查询性能。
|
12天前
|
SQL 人工智能 关系型数据库
DBA的AI助手:向量检索与NL2SQL入门
本篇为DBA量身打造的AI入门指南:用最直白语言讲清向量检索(相似搜索、pgvector实战)与NL2SQL(自然语言写SQL)的本质、场景及落地路径。不卷算法,只讲DBA真正需要懂的数据库新能力——技术迭代快,但掌握关键点,你依然不可替代。
|
2月前
|
SQL 数据库 数据库管理
从运营到DBA,我用了这3个“偷懒”方法学SQL
用运营人思维教小白轻松学SQL:①把SQL当Excel对话,理解SELECT/FROM/WHERE;②建“报错翻译本”,快速定位解决错误;③用“填空题法”抄改练,复用模板上手。不求完美,先跑通、看懂、不崩溃!
从运营到DBA,我用了这3个“偷懒”方法学SQL