想抓PostgreSQL里的慢SQL?pg_stat_statements基础黑匣子和pg_stat_monitor时间窗,谁能帮你更准揪出性能小偷?
url: /posts/b2213bfcb5b88a862f2138404c03d596/
title: 想抓PostgreSQL里的慢SQL?pg_stat_statements基础黑匣子和pg_stat_monitor时间窗,谁能帮你更准揪出性能小偷?
date: 2025-10-16T02:00:15+08:00
lastmod: 2025-10-16T02:00:15+08:00
author: cmdragon
summary:
pg_stat_statements
是PostgreSQL的核心性能监控模块,用于跟踪SQL语句的计划与执行统计信息,帮助定位性能瓶颈。通过修改配置文件并重启数据库,可以启用该模块。核心配置参数包括跟踪SQL的最大数量、跟踪范围等。pg_stat_statements
视图提供SQL的详细统计信息,如执行次数、总执行时间、缓存命中率等。pg_stat_monitor
是增强版模块,支持按时间窗口统计和响应时间直方图,适合持续监控。结合这两个模块,可以持续优化数据库性能,通过定位瓶颈SQL、分析执行计划、优化索引等步骤提升效率。
categories:
- postgresql
tags:
- 基础入门
- PostgreSQL
- 性能监控
- pg_stat_statements
- SQL优化
- 数据库管理
- 性能分析
- pg_stat_monitor

扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/
1. pg_stat_statements:基础性能统计模块
1.1 什么是pg_stat_statements?
pg_stat_statements
是PostgreSQL官方提供的核心性能监控模块,用于跟踪所有SQL语句的计划与执行统计信息。它能帮你回答:
- 哪些SQL执行次数最多?
- 哪些SQL总执行时间最长?
- 哪些SQL的缓存命中率最低(IO开销大)?
- 某条SQL的平均执行时间是多少?
简单来说,它是PostgreSQL性能优化的“黑匣子”——记录所有SQL的运行痕迹,帮你定位瓶颈。
1.2 安装与启用
pg_stat_statements
需要预加载(因为它需要共享内存),安装步骤分3步:
步骤1:修改配置文件
编辑postgresql.conf
(通常在/var/lib/postgresql/17/main/
或$PGDATA
目录):
# 1. 预加载模块(必须)
shared_preload_libraries = 'pg_stat_statements'# 2. 启用查询ID计算(必须,用于唯一标识相同结构的查询)
compute_query_id = on# 3. 可选配置(根据需求调整)
pg_stat_statements.max = 10000 # 最多跟踪10000条不同的SQL
pg_stat_statements.track = all # 跟踪顶级+嵌套语句(比如函数内的SQL)
pg_stat_statements.track_utility = on # 跟踪工具命令(如CREATE TABLE)
步骤2:重启PostgreSQL
修改配置后需要重启数据库使生效:
sudo systemctl restart postgresql
步骤3:创建扩展
登录数据库(如psql -U postgres
),执行以下命令启用扩展:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
1.3 核心配置参数解析
参数 | 作用 | 默认值 |
---|---|---|
pg_stat_statements.max | 最多跟踪多少条不同的SQL(超过则丢弃最不常用的条目) | 5000 |
pg_stat_statements.track | 跟踪范围:top (仅顶级语句)、all (顶级+嵌套)、none (不跟踪) | top |
pg_stat_statements.track_utility | 是否跟踪工具命令(如VACUUM 、CREATE ) | on |
pg_stat_statements.track_planning | 是否跟踪计划时间(会增加性能开销) | off |
pg_stat_statements.save | 重启后是否保留统计信息 | on |
1.4 关键视图与字段说明
pg_stat_statements
提供两个核心视图:
1.4.1 pg_stat_statements
:SQL统计详情
这个视图是性能分析的核心,每一行对应一条不同结构的SQL(用queryid
标识)。关键字段如下:
字段 | 含义 |
---|---|
queryid | SQL的唯一哈希ID(相同结构的SQL哈希值相同) |
query | SQL文本(常量会被替换为$1 、$2 ,比如SELECT * FROM users WHERE id = $1 ) |
calls | 执行次数 |
total_exec_time | 总执行时间(毫秒,最常用的慢查询指标) |
mean_exec_time | 平均执行时间(毫秒) |
rows | 总返回/影响的行数 |
shared_blks_hit | 共享缓存命中次数(越高越好,说明少读磁盘) |
shared_blks_read | 共享缓存未命中次数(需要读磁盘,IO开销大) |
stats_since | 统计开始时间 |
示例:计算缓存命中率(越高越好):
SELECT query,calls,total_exec_time,100.0 * shared_blks_hit / NULLIF(shared_blks_hit + shared_blks_read, 0) AS hit_percent
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 5;
1.4.2 pg_stat_statements_info
:模块自身统计
这个视图只有1行,记录模块的运行状态:
字段 | 含义 |
---|---|
dealloc | 因超过pg_stat_statements.max 而丢弃的SQL条目数(值大说明max 太小) |
stats_reset | 统计 |