文章资讯 / 云服务器 / MySQL慢查询优化:开启慢查询日志+pt-query-digest分析+索引优化的流程

MySQL慢查询优化:开启慢查询日志+pt-query-digest分析+索引优化的流程

发布时间: 分类:云服务器 作者:188mi 来源:互联网 阅读:109

MySQL慢查询优化可按“开日志、做分析、改索引、再验证”四步推进。先让慢查询日志留下真实样本,再用 pt-query-digest 找出大头,最后才动索引。顺序反了,等于盲调。

先确认慢查询日志能不能打开

启动前先查当前配置,别急着改文件。在 MySQL 客户端执行 SHOW VARIABLES LIKE 'slow_query_log%';、SHOW VARIABLES LIKE 'long_query_time';。前者返回 OFF,说明日志没开;后者是阈值,默认常见为 10 秒,可按需调小到 1 秒或 0.5 秒先采样。改配置文件时,在 my.cnf(Windows 为 my.ini)的 [mysqld] 段加入 slow_query_log=ON、slow_query_log_file=/var/log/mysql/slow.log、long_query_time=1,保存后重启服务。临时开启可执行 SET GLOBAL slow_query_log=ON; 和 SET GLOBAL long_query_time=1;,但重启会失效。云数据库入口不同:阿里云 RDS 通常在控制台 → 日志管理 → 慢日志;腾讯云 CDB 在实例 → 日志中心 → 慢查询日志。能直接下载就不折腾配置文件。log_queries_not_using_indexes 会记录未走索引的小查询,短期排查看可以,长期开会把日志撑大;log_output 先设 FILE,需要表存储再改 TABLE。以平台页面为准。

环节一:把慢日志交给 pt-query-digest

日志有样本后,登录服务器执行 pt-query-digest /var/log/mysql/slow.log > slow_report.txt。只看最近一天加 --since '24h',只看某库加 --filter '$event->{db} =~ /your_db/'。报告会按 Query_time、Lock_time、Rows_examined、Rows_sent 聚合同类 SQL,给出总耗时占比、执行次数和平均耗时。优先看总耗时占比高且执行次数多的语句,其次看单次扫描行数远大于返回行数的语句。别被单条偶发慢查询带偏,分组统计比逐条翻日志有效。若日志来自云平台,先下载到本地再跑,避免在控制台直接分析大文件。机器内存有限时,可先 gzip 压缩旧日志,或用 --limit 控制处理量。

流程节点:从报告里挑出值得改的 SQL

不是每条慢 SQL 都值得加索引。先判断类型:统计报表、后台批处理、用户高频查询,还是偶发管理操作。高频读查询优先优化;写多读少的表要谨慎,因为每个索引都会增加写入成本;低频一次性任务可以接受全表扫描。把候选 SQL 复制到测试库,执行 EXPLAIN SELECT ...。重点看 type 是否出现 ALL,key 是否为空,rows 估算行数,Extra 是否出现 Using filesort 或 Using temporary。MySQL 8.0 可用 EXPLAIN ANALYZE 看实际执行时间。确认瓶颈在扫描行数、排序还是临时表。若 WHERE 条件区分度太低,例如性别、状态只有几种值,单独加索引往往没效果,需要和更高区分度字段组合。

索引优化的判断顺序

先看 WHERE 条件,把等值条件放联合索引前面,范围条件放后面。再考虑 ORDER BY、GROUP BY 能否复用同一索引,避免额外排序。能覆盖查询就做覆盖索引,即索引里包含 SELECT 需要的列,减少回表。常见坑包括:在索引列上用函数、隐式类型转换、前导通配符 LIKE '%xxx'、联合索引跳过最左列。加索引可用 ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);,上线前在测试库跑一遍,观察写入耗时。删除旧索引前,用 pt-index-usage 分析慢日志里哪些索引没被用到,再决定是否清理冗余索引。以平台页面为准。

改完要回看:验证与防回归

优化后不能只看“感觉快了”。重新开启慢查询日志,观察同一时段慢日志条数和 pt-query-digest 报告里的总耗时是否下降。用 SHOW STATUS LIKE 'Handler_read%'; 看扫描行数变化,用 SHOW INDEX FROM 表名; 确认索引真的建上。业务侧对比接口 P95、P99 延迟。若写入变慢,检查是否加了过多索引。把本次分析用的 SQL、执行计划、索引变更记入变更记录,下次同类问题直接复用。慢查询优化不是一次性任务,流量结构变化后要重新采样。

阶段:把变更放进低峰窗口

真正执行 ALTER TABLE 前,先确认表的数据量和存储引擎。大表加索引可能锁表或占用大量 IO,InnoDB 在 MySQL 5.6 以后支持在线 DDL,但不同版本、不同云平台行为有差异。低峰窗口执行,准备好回滚语句,观察主从延迟。若使用云数据库,部分平台提供无锁变更或 DBA 助手,入口一般在实例 → 数据库管理 → 结构变更。变更后立即跑一遍核心查询,确认执行计划走对索引。慢查询优化最终看稳定收益,不是单次跑分。

相关工具与阅读