如何定位慢sql_mysql性能问题排查

来源:这里教程网 时间:2026-02-28 20:38:55 作者:

定位慢 SQL 是 MySQL 性能排查中最常见也最关键的一步。核心思路是:先找到“谁慢”,再分析“为什么慢”。不靠猜,靠日志、指标和执行计划。

开启并查看慢查询日志

慢查询日志是定位问题的第一手依据。默认通常关闭,需手动启用:

在 my.cnf 中添加:slow_query_log = ONslow_query_log_file = /var/log/mysql/slow.loglong_query_time = 1(单位秒,建议设为 0.5~2,根据业务调整) 动态开启(无需重启):SET GLOBAL slow_query_log = ON;SET GLOBAL long_query_time = 1; 注意:log_queries_not_using_indexes = ON 可额外记录未走索引的查询,但生产环境慎开,日志量可能激增

用 pt-query-digest 快速分析慢日志

原生日志可读性差,推荐用 Percona Toolkit 的 pt-query-digest 做聚合分析:

命令示例:pt-query-digest /var/log/mysql/slow.log --limit 10,输出按响应时间、执行次数排序的 Top SQL 关键看三列:Rank(影响排名)、Query_time(总耗时占比)、Rows_examined(扫描行数)——高 Rows_examined 往往意味着缺失索引或索引失效 它还能生成报告 HTML,带执行计划摘要和样例语句,适合团队共享

对慢 SQL 手动分析执行计划(EXPLAIN)

拿到具体 SQL 后,用 EXPLAIN FORMAT=TRADITIONALEXPLAIN ANALYZE(MySQL 8.0.18+)看真实执行路径:

重点关注:type(是否用到高效访问类型,如 const/ref;避免 ALL/index)、key(实际使用的索引)、rows(预估扫描行数,远大于返回行数就危险)、Extra(警惕 Using filesort、Using temporary、Using join buffer) 常见陷阱:WHERE 子句中对字段做函数操作(如 YEAR(create_time) = 2024)会跳过索引联合索引顺序错(如索引是 (a,b),却只查 b)隐式类型转换(如字符串字段 vs 数字参数)导致索引失效

结合 Performance Schema 实时抓取活跃慢查询

当慢日志来不及捕获或想看“正在发生”的问题时,Performance Schema 更及时:

开启相关消费者:UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%statements%'; 查当前执行超时的语句:SELECT * FROM performance_schema.events_statements_current WHERE TIMER_WAIT > 1000000000000 LIMIT 5;(1e12 纳秒 = 1 秒) 配合 events_statements_history_long 可回溯最近几百条慢语句,适合突发抖动场景

不复杂但容易忽略:别只盯着单条 SQL,要结合 QPS、连接数、InnoDB 状态(如 SHOW ENGINE INNODB STATUS)判断是孤立问题还是系统性瓶颈。定位慢 SQL 是起点,优化才是闭环。

相关推荐