如何在mysql中分析慢查询日志发现索引问题

7次阅读

开启慢查询日志并设置 long_query_time= 1 和 log_queries_not_using_indexes=ON,利用 mysqldumpslow 分析日志中 Rows_examined 远大于 Rows_sent 的语句,结合 EXPLAIN 检查 type、key、rows 及 Extra 字段,识别全表扫描或索引未使用问题,针对 WHERE 条件无索引、复合索引顺序不当、函数操作、数据类型不匹配等常见问题创建或调整索引,持续监控以优化 SQL 性能。

如何在 mysql 中分析慢查询日志发现索引问题

在 MySQL 中,慢查询日志是发现 性能瓶颈 、尤其是索引问题的重要 工具。通过分析执行缓慢的 SQL 语句,可以识别出缺失索引、索引未命中或低效使用索引的情况。以下是具体的操作步骤和分析方法。

开启并配置慢查询日志

确保慢查询日志已启用,并设置合理的阈值来捕获需要关注的查询:

1. 在 my.cnf 或 my.ini 配置文件 中添加以下内容:

  • slow_query_log = ON
  • slow_query_log_file = /var/log/mysql/slow.log
  • long_query_time = 1(超过 1 秒的查询会被记录)
  • log_queries_not_using_indexes = ON(记录未使用索引的查询)

2. 重启 MySQL 或动态启用:

SET GLOBAL slow_query_log = ‘ON’;
SET GLOBAL long_query_time = 1;
SET GLOBAL log_queries_not_using_indexes = ‘ON’;

使用 mysqldumpslow 分析日志

MySQL 提供了 mysqldumpslow 工具用于汇总和分析慢查询日志。

常用命令示例:

  • mysqldumpslow -s at -t 10 /var/log/mysql/slow.log:显示平均执行时间最长的前 10 条语句
  • mysqldumpslow -s c -t 10 /var/log/mysql/slow.log:按出现次数排序,找出最频繁的慢查询
  • mysqldumpslow -g “SELECT” /var/log/mysql/slow.log:筛选包含 SELECT 的慢查询

重点关注输出中的 Rows_examined(扫描行数)和 Rows_sent(返回行数)。若前者远大于后者,说明查询做了大量无效扫描,很可能缺少有效索引。

结合 EXPLAIN 分析具体 SQL

从慢日志中提取典型慢查询,使用 EXPLAIN 查看执行计划,判断索引使用情况。

执行方式:

EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = ‘pending’;

关键字段解读:

  • type:ALL 表示全表扫描,需优化;index 或 range 更好;ref 或 const 最佳
  • key:实际使用的索引,为 NULL 说明未用索引
  • rows:估算扫描行数,数值大说明效率低
  • Extra:出现 Using filesort 或 Using temporary 是严重性能警告

如果 WHERE 条件中的字段没有索引,或者复合索引顺序不匹配,都可能导致索引失效。

常见索引问题与优化建议

根据分析结果,常见的索引问题包括:

  • WHERE 条件字段无索引 → 为高频过滤字段创建单列或复合索引
  • 复合索引顺序不合理 → 按照最左前缀原则调整索引列顺序
  • 索引选择性差 → 避免在区分度低的字段(如性别)上单独建索引
  • 查询中对字段使用函数 → 如 WHERE YEAR(create_time) = 2024,导致索引失效,应改写为范围查询
  • 数据类型不匹配 → 字符串字段用数字查询,引发 隐式类型转换,使索引失效

创建索引后,再次运行 EXPLAIN 确认是否命中,并观察慢日志中该语句是否消失。

基本上就这些。关键是持续监控慢查询日志,定期分析并结合执行计划验证索引有效性。不复杂但容易忽略的是 log_queries_not_using_indexes 这个选项,它能帮你快速定位“看似正常却全表扫描”的查询。

text=ZqhQzanResources