← 中文资源

简体中文版本

添加 PostgreSQL 慢查询日志

用合理的阈值开启慢查询日志,借助 pg_stat_statements 聚合分析,并在不记录敏感参数的情况下检查执行计划。

阅读英文原文

单次耗时不是全部

一个耗时 200 毫秒但每分钟执行一万次的查询,比每小时执行一次、耗时五秒的报表更重要。pg_stat_statements 按归一化查询聚合调用次数、总执行时间和平均时间,使排名反映工作负载影响。慢查询日志用于捕获阈值附近的具体语句和计划,扩展用于发现频率。

SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

看计划,而不只看 SQL

用代表真实流量的参数执行 EXPLAIN (ANALYZE, BUFFERS)。小表上的顺序扫描没有问题;大表在过滤条件下列顺序扫描则不是。关注行数估计误差、大输入上的嵌套循环以及临时落盘。比较加索引前后的计划,并确认优化器确实使用了索引。

EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE customer_id = 42 AND created_at > now() - interval '7 days';

保护日志

慢查询日志可能包含字面量中的个人数据。限制访问、集中保留,并优先使用参数化查询,避免值嵌入语句文本。不要为了弥补缺少仪表盘而在生产设置 log_statement = 'all',它会成倍增加日志量和暴露面。轮转日志并对日志量突增告警,这可能意味着新的查询模式或攻击。

形成闭环

添加缺失索引、重写查询或改变访问模式后,用相同负载验证。持续跟踪头部查询的总时间和调用次数。没有人查看的慢查询仪表盘不是可观测性;应指定负责人和复查节奏。