如何排除慢查询日志中的锁等待时间,仅查看实际耗时高的查询?
排除慢查询日志中的锁等待时间,筛选真实耗时查询
针对MySQL的解决方案
精准配置慢查询过滤规则
在MySQL 5.6及以上版本,可通过log_slow_filter参数剔除仅因锁等待触发的慢查询。修改my.cnf(或my.ini)配置:log_slow_filter = admin,filesort,filesort_on_disk,full_join,full_scan,query_cache_miss,tmp_table,tmp_table_on_disk该配置会排除
lock_wait相关的触发条件,只记录因查询自身执行效率低(如全表扫描、临时表生成等)导致的慢查询。用Performance Schema直接计算真实耗时
借助Performance Schema的事件表,可分离总耗时与锁等待时间,筛选真实执行时间达标的查询:SELECT SQL_TEXT, ROUND(TIMER_WAIT/1000000000, 2) AS total_time_sec, ROUND(LOCK_TIME/1000000000, 2) AS lock_wait_sec, ROUND((TIMER_WAIT - LOCK_TIME)/1000000000, 2) AS actual_exec_time_sec FROM performance_schema.events_statements_history_long WHERE (TIMER_WAIT - LOCK_TIME)/1000000000 > 2; -- 替换为你的真实耗时阈值离线解析已生成的慢查询日志
若已有慢查询日志,可通过脚本提取Query_time和Lock_time字段,计算真实耗时后筛选:awk '$1 == "Query_time:" && ($2 - $10) > 2' slow_query.log上述脚本会筛选真实执行时间(总耗时-锁等待时间)超过2秒的查询条目。
针对PostgreSQL的解决方案
利用pg_stat_statements分离耗时
启用pg_stat_statements扩展后,可通过字段计算排除IO和锁等待相关耗时,筛选真实执行时间高的查询:SELECT queryid, LEFT(query, 200) AS query_sample, ROUND((total_time - blk_read_time - blk_write_time)/calls/1000, 2) AS avg_actual_exec_time_sec FROM pg_stat_statements WHERE (total_time - blk_read_time - blk_write_time)/calls > 2000; -- 筛选平均真实耗时超2秒的查询调整日志配置避免锁等待干扰
将log_lock_waits设为off,关闭单独的锁等待日志记录;同时通过log_min_duration_statement仅记录实际执行时间超过阈值的查询,减少无效日志条目。
内容的提问来源于stack exchange,提问作者alexl
相关产品推荐
相关产品推荐

