,

pg慢查询排查

PostgreSQL 查慢查询主要有三招: 一、实时看当前正在执行的慢语句 duration 超过你预期(比如…

PostgreSQL 查慢查询主要有三招:

一、实时看当前正在执行的慢语句

SELECT pid,       now() - query_start AS duration,       state,       queryFROM pg_stat_activityWHERE state = 'active'  AND query NOT ILIKE '%pg_stat_activity%'ORDER BY duration DESC;

duration 超过你预期(比如几秒)的就是正在跑的慢查询。看到卡死的可以用 SELECT pg_terminate_backend(pid); 杀掉。

二、记录慢查询日志(事后排查)

修改 postgresql.conf:

log_min_duration_statement = 1000   # 超过1000ms的语句记日志,0表示全记log_line_prefix = '%t [%p]: user=%u,db=%d '  # 日志带上时间/用户/库名

改完执行 SELECT pg_reload_conf(); 生效(不用重启)。慢语句会写到 PG 日志文件里。

临时只对当前会话生效(调试用,不动全局配置):

SET log_min_duration_statement = 500;

三、pg_stat_statements(统计历史慢查询,最实用)

开启(一次性配置):

# postgresql.confshared_preload_libraries = 'pg_stat_statements'

这个要重启 PG 才生效。然后在你业务库里执行:

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

查询耗时 TOP:

-- 按总耗时排序,揪出最拖系统的语句SELECT calls,       round(total_exec_time::numeric, 2)        AS total_ms,       round(mean_exec_time::numeric, 2)         AS avg_ms,       round(max_exec_time::numeric, 2)          AS max_ms,       rows,       left(query, 200)                          AS queryFROM pg_stat_statementsORDER BY total_exec_time DESCLIMIT 20;
-- 按平均耗时排序(找单次慢但次数少的)SELECT calls, round(mean_exec_time::numeric,2) AS avg_ms, left(query,200)FROM pg_stat_statementsORDER BY mean_exec_time DESCLIMIT 20;

看完想清空重新统计:SELECT pg_stat_statements_reset();

找到慢语句后的分析

拿到具体 SQL 后,用它实际执行:

EXPLAIN (ANALYZE, BUFFERS) <慢查询SQL>;

重点看:Seq Scan(全表扫描,多半缺索引)、rows 预估和实际差很多(统计信息过期,跑 ANALYZE 表名)、Nested Loop 行数爆炸。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Latest News

View All

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor

You May Have Missed