慢查询日志默认不记录执行耗时;mysql 5.7+默认未启用log_slow_extra时,日志仅含时间戳、用户、库名等信息,不包含# query_time:字段,需显式开启该配置才显示具体耗时。

慢查询日志默认记录的是执行时间吗?
不是。MySQL的慢查询日志(slow_query_log)本身不直接记录SQL的“执行耗时”,而是根据long_query_time阈值,把超过该时间的语句写入日志——但日志中是否包含具体耗时,取决于log_output格式和log_slow_extra配置。
默认情况下(MySQL 5.7+),如果log_output = FILE且未启用log_slow_extra,日志里只有SQL文本、时间戳、用户、库名、锁等待时间等,没有query_time字段;而启用log_slow_extra后,才会在每条日志开头明确写出# Query_time: 0.123456这类行。
-
long_query_time单位是秒,支持微秒精度(如0.1表示100ms) -
log_slow_extra是关键开关:MySQL 8.0.14+默认ON,5.7需手动设为ON - 即使
long_query_time = 0,也不代表记录所有SQL——还受log_queries_not_using_indexes等限制
如何确认日志里有没有Query_time字段?
直接看日志文件最可靠。用tail -n 20 /var/lib/mysql/xxx-slow.log查最新几条,观察是否有以# Query_time:开头的行:
# Time: 2024-06-10T09:12:34.567890 # User@Host: app[app] @ localhost [127.0.0.1] # Query_time: 0.234567 Lock_time: 0.000123 Rows_sent: 1000 Rows_examined: 5000 use test_db; SET timestamp=1717996354; SELECT * FROM orders WHERE created_at > '2024-06-01';
如果没有# Query_time:行,说明log_slow_extra没开,或MySQL版本太低(
- 检查当前配置:
SHOW VARIABLES LIKE 'log_slow_extra'; - 临时启用:
SET GLOBAL log_slow_extra = ON;(需SUPER权限) - 永久生效:在
my.cnf的[mysqld]下加log_slow_extra = ON
log_output = TABLE时Query_time在哪?
当log_output = 'TABLE'(即日志写入mysql.slow_log表),query_time字段是存在的,但它是TIME类型,精度只到秒(MySQL 5.7)或微秒(8.0+),且log_slow_extra对表格式无效——query_time始终存在,但额外字段(如rows_sent、rows_examined)仍需log_slow_extra才能写入。
- 查表确认:
SELECT query_time, sql_text FROM mysql.slow_log ORDER BY start_time DESC LIMIT 5; - 注意:
query_time列值可能为NULL——这通常是因为语句被截断或解析失败,不是配置问题 - 表格式日志无法直接看到Lock_time、Rows_sent等细节,除非
log_slow_extra = ON且MySQL ≥8.0.23
为什么有些SQL明明很慢却没进慢日志?
常见原因不是时间没超阈值,而是根本没被判定为“可记录的查询”:
- SQL是管理命令(如
SHOW PROCESSLIST、SET语句)——不会记入慢日志 - 查询被优化器短路(如
SELECT 1),实际执行时间极短,但逻辑上应快,MySQL可能跳过计时 -
long_query_time对事务内语句的计时起点是语句开始执行,不是事务开始;如果事务里前几条快、最后一条慢,只有最后一条可能触发记录 - 从库复制线程执行的SQL(
sql_slave_skip_counter相关)默认不记录,需显式开启log_slow_slave_statements
真正想抓全量耗时,得结合Performance Schema(events_statements_history_long)或代理层(如ProxySQL)做采样,慢日志只是第一道粗筛。











