首页/数据/数据库速查/未走索引日志与节流(log_queries_not_using_indexes)
性能与调优57 条

未走索引日志与节流(log_queries_not_using_indexes)

记录未用索引的查询能尽早发现隐患,但高并发下会写爆日志:必须配合 log_throttle_queries_not_using_indexes 节流,或仅短时开启排查。

数据库速查数据更新于 2026-10-13

未用索引日志与节流是什么

log_queries_not_using_indexes 让 MySQL 把「没有使用索引」的查询也记进慢日志——即使它们执行很快。对新上线系统来说这是发现隐患的好工具:小表全扫现在很快,数据量涨起来就会变成瓶颈。但它的问题也很直接:小表全扫、只返回少量行的查询会被大量记录,高并发下日志量能迅速撑爆磁盘,因此必须配合 log_throttle_queries_not_using_indexes 节流,或者只短时开启。

基本信息

开关log_queries_not_using_indexes,默认关闭
节流log_throttle_queries_not_using_indexes,单位是每分钟记录条数
生效条件仅在慢日志开启(slow_query_log=ON)时才有输出
记录范围未使用索引的查询,与是否超过 long_query_time 无关
建议用法新系统短开一段时间,稳定系统关闭后改用主动巡检

典型使用场景

  • 新系统上线期:短时开启一到两周,收集潜在的缺索引查询
  • 代码评审辅助:上线新功能后开启,验证新 SQL 是否走了索引
  • 压测阶段:压测环境开启,把所有未走索引的语句一次性列出来
  • 变更后核查:加完索引后复查是否还有未用索引的查询残留
  • 容量预警:结合扫描行数发现那些「现在快但迟早慢」的语句

短时开启与节流

短时开启与节流
-- 先开启节流,避免日志被瞬时打满
SET GLOBAL log_throttle_queries_not_using_indexes = 10;   -- 每分钟最多 10 条
SET GLOBAL log_queries_not_using_indexes = ON;
-- 排查结束后立刻关闭
SET GLOBAL log_queries_not_using_indexes = OFF;
-- 落库模式下可以直接聚合查看(配合 log_output=TABLE)
SELECT COUNT(*) FROM mysql.slow_log WHERE sql_text NOT LIKE '%mysql.%';
-- 确认开关状态
SHOW VARIABLES LIKE 'log_queries_not_using_indexes';

参数读法

参数含义设置建议
log_queries_not_using_indexes记录未用索引的查询短时开启,长期保持关闭
log_throttle_queries_not_using_indexes每分钟最多记录条数0 表示不限制,生产建议设小值
slow_query_log慢日志总开关关闭时上面的参数不产生任何输出
忘记关闭是这类功能的典型事故路径:日志文件或 mysql.slow_log 快速膨胀,写满磁盘后连带影响实例可用性。开启时应同时设定复查时间点与磁盘告警。
记录到未用索引不等于必须加索引:只有几十行的小表全扫成本极低,盲目加索引反而增加写入开销。判断依据是数据增长趋势与扫描行数。

易错点

  • 开启后忘记关闭或未设节流:日志量暴涨写满磁盘,本身变成事故源
  • 为所有被记录的语句加索引:小表全扫代价很低,加索引得不偿失,先区分表规模与增长趋势
  • 以为它是慢查询统计:它统计的是「未用索引」而非「耗时」,两者交叉核对才有意义
  • 在慢日志关闭的情况下打开该开关就以为在记录:总开关关闭时不会产生任何输出
  • 用未用索引日志替代 EXPLAIN:日志给的是线索,具体优化仍要结合 EXPLAIN 与扫描行数分析

数据来源与参考

  • MySQL 8.0 Reference Manual: log_queries_not_using_indexes

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌