MySQL慢查询日志为何不记录特定SQL

作者:技术拾光

时间:2026-05-20

浏览:258

慢查询日志未记录特定SQL,可能因其未达到判定标准。需确认开关、路径及阈值参数已正确开启。执行耗时仅计算纯执行时间,不含锁等待。默认配置下,管理语句、无索引查询及扫描行数过少的查询可能被豁免。阈值采用微秒级“严格小于”逻辑,建议设置略低于目标值以预留安全余量。

文章目录

MySQL慢查询日志为何记录不到特定SQL?分析执行流中LongQueryTime阈值

MySQL慢查询日志为何不记录特定SQL

当遇到一条执行明显很慢的SQL,却在慢查询日志里找不到记录时,确实令人困惑。首先不必怀疑日志功能本身,更常见的情况是:这条SQL在MySQL内部的执行流中,根本没有被判定为“慢查询”。 实际上,long_query_time这个参数的生效时机和判定逻辑,远比配置文件中简单的数字设置要复杂和严格。

为何SELECT SLEEP(5)都不记录?先确认三重开关是否全开

MySQL捕获慢查询依赖一套“三重门”机制,开关、输出路径和阈值必须同时生效,缺一不可:

  • slow_query_log = ON:这是总开关。关键细节在于,它必须被设置为字符串'ON'(而非数值1或布尔值TRUE)。最可靠的验证方法是执行SHOW VARIABLES LIKE 'slow_query_log',确认返回值就是ON。
  • log_output = 'FILE':这个参数决定日志去向。默认值为'NONE',意味着不记录。只有将其设为'FILE'(或'TABLE'),日志才会写入slow_query_log_file指定的文件。
  • long_query_time:这个浮点数阈值只对新建立的连接会话生效。如果在修改全局参数后没有断开重连,当前会话使用的仍是旧值。务必通过SELECT @@long_query_time来确认当前会话实际生效的阈值。

long_query_time判定发生在何时?不包含锁等待时间

MySQL内部使用my_micro_time()等高精度函数记录语句的开始时间,并与执行结束时间进行比对。但这里存在一个关键“盲区”:计算耗时时,不包含锁等待的时间。

例如:

  • 一条UPDATE语句本身的逻辑执行只花了20毫秒。
  • 但由于目标行被其他事务锁定,它在队列中等待了800毫秒才得以执行。
  • 最终,从客户端角度看,这条语句总耗时是820毫秒。

然而,在MySQL的慢查询判定逻辑里,只将那20毫秒的“纯执行时间”与long_query_time进行比较。如果阈值设为0.1秒(100毫秒),这条语句就不会被记录。这种现象在高并发更新场景下极为常见,你可以在information_schema.processlist中看到State显示为'Locked'或'Waiting for table metadata lock',但这些“等待型”慢查询却在慢日志里神秘消失了。

哪些SQL天然逃过long_query_time判定?管理语句、未走索引、低扫描行数

即使执行时间远超阈值,以下几类语句在默认配置下也会“豁免”记录:

  • 管理语句:当log_slow_admin_statements = OFF(默认值)时,像ALTER TABLE、ANALYZE TABLE、OPTIMIZE TABLE这类管理命令,即使运行了5分钟也不会进入慢日志。
  • 未使用索引的查询:参数log_queries_not_using_indexes默认也是OFF。这意味着,全表扫描的查询无论多慢都不会被记录。即使开启此选项,还需注意log_throttle_queries_not_using_indexes参数,它会限制每分钟记录此类查询的数量,防止日志被刷爆。
  • 扫描行数过少的查询:如果设置了min_examined_row_limit > 0(例如设为1000),那么即使查询耗时达标,但只要EXPLAIN显示其rows_examined(检查的行数)小于1000,同样会被跳过记录。

最易忽略的精度陷阱:long_query_time = 0.1不等于“≥100ms就记”

MySQL内部使用微秒级精度进行计时,但其判定逻辑是“严格小于”,而非四舍五入或向上取整。这导致了一个微妙的精度陷阱:

  • 假设设置long_query_time = 0.1(即100毫秒)。
  • 一条真实耗时为0.099999秒(即99999微秒)的查询,不会被记录。
  • 它距离阈值只差了1微秒。而在生产环境中,网络延迟、系统上下文切换、CPU调度抖动都可能轻易“吃掉”这1微秒。

因此,一个实用的建议是:在生产环境中,将阈值设得略低于你的目标值,例如设为0.099或0.09,为系统波动留出安全余量。在测试时,可以用SLEEP(0.11)来验证配置是否真的能捕获到超时查询。

总结来说,最难调试的问题往往不是配置开关没打开,而是你以为应该被记录的那条SQL,在MySQL执行引擎的判定体系里,压根就没有触达那个关于“慢”的、严格且多条件的定义边界。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章