PgSQL中pg_stat_user_tables 和 pg_stat_user_objects参数详解

pg_stat_user_tables 和 pg_stat_user_objects 是PostgreSQL 中两个 非常重要的性能监控和统计视图。

核心概念

这两个视图都属于 PostgreSQL 的**统计收集器(Statistics Collector)**子系统。它们提供了关于数据库对象使用情况和性能的宝贵信息,是进行数据库性能分析、瓶颈排查和SQL调优的基石。

要确保这些视图中有数据,必须先确认 track_counts 参数是 on 的(默认通常是开启的)。

sql 复制代码
SHOW track_counts;

1. pg_stat_user_tables

这个视图专门用于收集和显示当前数据库中用户定义表的统计信息。每个用户表对应一行记录。

主要字段详解

这些字段通常从最后一次重置统计信息(使用 pg_stat_reset())或者数据库启动开始累积。

字段名 类型 描述
relid OID 表的对象标识符(OID)
schemaname name 表所在的模式名(如 public)
relname name 表的名字
seq_scan bigint 在此表上发起的顺序扫描(全表扫描)的次数
seq_tup_read bigint 顺序扫描读取的活元组(行)数(可能包含已删除但未清理的行)
idx_scan bigint 在此表上所有索引的索引扫描总次数
idx_tup_fetch bigint 通过索引扫描读取的活元组数
n_tup_ins bigint 插入的行数
n_tup_upd bigint 更新的行数(包含HOT更新和不HOT更新)
n_tup_del bigint 删除的行数
n_tup_hot_upd bigint HOT(仅堆元组)更新的行数。HOT更新是一种优化,避免更新索引。
n_live_tup bigint 表中当前估算的活元组数(是估算值,非精确值)
n_dead_tup bigint 表中当前估算的死元组数(是估算值,是VACUUM的主要目标)
n_mod_since_analyze bigint 自上次分析(ANALYZE)以来插入、更新或删除的估算行数
last_vacuum timestamp 最后一次手动或自动VACUUM此表的时间
last_autovacuum timestamp 最后一次autovacuum守护进程清理此表的时间
last_analyze timestamp 最后一次手动ANALYZE此表的时间
last_autoanalyze timestamp 最后一次autoanalyze守护进程分析此表的时间
vacuum_count bigint 此表被手动VACUUM的次数
autovacuum_count bigint 此表被autovacuum进程清理的次数
analyze_count bigint 此表被手动ANALYZE的次数
autoanalyze_count bigint 此表被autoanalyze进程分析的次数
经典使用场景和查询示例
  1. 识别全表扫描过多的表

    顺序扫描成本很高,特别是对大表。如果一个表频繁被全表扫描,应考虑为查询条件添加索引。

    sql 复制代码
    SELECT schemaname, relname, seq_scan, seq_tup_read,
           seq_tup_read / NULLIF(seq_scan, 0) AS avg_tuples_per_scan
    FROM pg_stat_user_tables
    WHERE seq_scan > 0
    ORDER BY seq_tup_read DESC
    LIMIT 10;
  2. 评估索引使用情况

    检查哪些表"读多写少"但索引使用率却很低,这些表可能是添加索引的候选。

    sql 复制代码
    SELECT schemaname, relname, seq_scan, idx_scan,
           n_tup_ins, n_tup_upd, n_tup_del,
           CASE WHEN (seq_scan + idx_scan) > 0
                THEN (idx_scan * 100.0) / (seq_scan + idx_scan)
                ELSE 0
           END AS idx_scan_pct
    FROM pg_stat_user_tables
    ORDER BY n_tup_ins + n_tup_upd + n_tup_del DESC; -- 按写入量排序

    如果 idx_scan_pct 很低,但表读取量(seq_tup_read)很高,说明查询可能没走索引。

  3. 监控死元组和自动清理状态

    死元组过多会导致表膨胀、查询性能下降。这是监控autovacuum工作的核心视图。

sql 复制代码
SELECT schemaname, relname,
       n_live_tup, n_dead_tup,
       (n_dead_tup * 100.0 / NULLIF((n_live_tup + n_dead_tup), 0)) AS dead_tup_ratio,
       last_autovacuum, last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;
python 复制代码
注:此SQL用了NULLIF函数,这是最简洁和高效避免报错ERROR:division by zero的方法:
- 在除数为零时返回 NULL
- 避免了除零错误
- 代码简洁易读
- NULLIF() 函数会在 (n_live_tup + n_dead_tup) 为零时返回 NULL,而任何数除以 NULL 都会返回 NULL,从而避免错误。

SQL报错解决方案链接:https://blog.csdn.net/liumangtuzi888/article/details/151362257?sharetype=blogdetail\&sharerId=151362257\&sharerefer=PC\&sharesource=liumangtuzi888\&spm=1011.2480.3001.8118

如果 dead_tup_ratio 过高且 last_autovacuum 是很久以前,可能需要调查autovacuum为何没有正常工作。

  1. 查看表的数据变更频率

    sql 复制代码
    SELECT schemaname, relname,
           n_tup_ins AS inserts,
           n_tup_upd AS updates,
           n_tup_del AS deletes,
           (n_tup_ins + n_tup_upd + n_tup_del) AS total_changes
    FROM pg_stat_user_tables
    ORDER BY total_changes DESC
    LIMIT 10;

2. pg_stat_user_objects

有些PostgreSQL 版本不支持此视图

这个视图提供了更上层、更概括的统计信息,它涵盖了所有用户定义的对象(表、索引、序列、视图、物化视图等),但每个对象只有一行非常基础的统计信息。

主要字段详解
字段名 类型 描述
relid OID 对象的对象标识符(OID)
schemaname name 对象所在的模式名
relname name 对象的名字
relkind char 对象类型标识 : r = 普通表 i = 索引 S = 序列 v = 视图 m = 物化视图 c = 组合类型 t = TOAST表 f = 外表
relpages bigint 磁盘上表示该关系的页数(尺寸的近似值,基于last vacuum或analyze)
reltuples bigfloat 表中的行数(尺寸的近似值,基于last vacuum或analyze)

注意 :pg_stat_user_objects 没有 seq_scan, n_tup_ins 等详细的I/O或DML统计信息。那些信息在更专门的视图里(如 pg_stat_user_tables, pg_statio_user_indexes)。

经典使用场景和查询示例
  1. 获取数据库中所有用户对象的大小估算

    这是一个快速查看对象大小和行数的概览方法。

    sql 复制代码
    SELECT schemaname,
           relname,
           CASE relkind
               WHEN 'r' THEN 'ordinary table'
               WHEN 'i' THEN 'index'
               WHEN 'S' THEN 'sequence'
               WHEN 'v' THEN 'view'
               WHEN 'm' THEN 'materialized view'
               ELSE 'other'
           END AS object_type,
           pg_size_pretty(pg_relation_size(relid)) AS size, -- 更精确的大小
           reltuples::bigint AS estimated_rows
    FROM pg_stat_user_objects
    ORDER BY pg_relation_size(relid) DESC;
  2. 查找最大的表和索引

    sql 复制代码
    SELECT schemaname, relname,
           CASE WHEN relkind = 'i' THEN 'INDEX' ELSE 'TABLE' END AS type,
           pg_size_pretty(pg_relation_size(relid)) AS size
    FROM pg_stat_user_objects
    WHERE relkind IN ('r', 'i') -- 只查表和索引
    ORDER BY pg_relation_size(relid) DESC
    LIMIT 20;

核心区别与联系

特性 pg_stat_user_tables pg_stat_user_objects
范围 仅限用户表 所有用户对象(表、索引、序列、视图等)
统计粒度 非常详细:包含扫描、读写、元组、 vacuum 等 非常基础:主要是对象类型和大小估算
主要用途 性能调优:查询分析、索引优化、Vacuum监控 对象管理:尺寸监控、对象清单浏览
关系 它是 pg_stat_user_objects 的一个子集和详细补充。 它是所有用户对象的一个概览目录。

重置统计信息

你可以使用以下函数重置统计信息(通常需要超级用户权限)。谨慎操作,因为这会使历史趋势数据丢失。

python 复制代码
-- 重置当前数据库的所有统计信息
SELECT pg_stat_reset();

-- 重置单个表的统计信息
SELECT pg_stat_reset_single_table_counters(<table_oid>);
SELECT pg_stat_reset_single_function_counters(<function_oid>);

总结

  • 当你需要深入分析表的访问模式、I/O性能、DML操作和Vacuum状态 时,使用 pg_stat_user_tables。这是DBA进行日常性能诊断最常用的视图之一。
  • 当你需要快速查看数据库中有哪些对象、它们的类型和大致大小 时,使用 pg_stat_user_objects 。它更像一个增强版的 pg_class 视图,附带了一些统计信息。

通常,你会从 pg_stat_user_objects 找到一个感兴趣的大对象,然后通过它的 relid 和 relkind 去更专门的统计视图(如 pg_stat_user_tables 或 pg_statio_user_indexes)中获取其详细性能数据。

相关推荐
刚入门的大一新生10 小时前
Linux-线程控制
linux·运维·服务器
Decay__11 小时前
03_MySQL 存储引擎与存储管理 —— InnoDB 深入、表空间/ibd、binlog/redo/undo 与双写缓冲
运维·数据库·sql·mysql·架构
Z21-X11 小时前
云原生运维笔记:打通OpenStack的任督二脉——从Neutron网络踩坑到Swift与Heat硬核实战
运维·笔记·学习·云原生
瀚高PG实验室11 小时前
瀚高数据库提交数据后,是否需要COMMIT
数据库·postgresql·瀚高数据库
C++ 老炮儿的技术栈11 小时前
Linux 动态库踩坑:明明重新编译了 .so,调用函数返回值却一直不变(libfjrobot.so 版本号异常排查实录)
linux·c语言·网络·c++·visual studio
bksczm11 小时前
MySQL程序架构
数据库·mysql·架构
论文复现现场11 小时前
2026 低成本 AI Agent 模型怎么选?DeepSeek V4.1 Flash、Qwen3.8 Flash、GLM-5.3 Flash 对比
数据库·人工智能·qwen·ai agent·glm·deepseek
你看我名字12 小时前
云计算工程师技能树:从 Linux 基础到云平台架构能力
linux·架构·云计算
广州灵眸科技有限公司19 小时前
4G 模组开机自连 systemd 服务方案:基于灵眸科技EAI1106--Core-T
运维·服务器·科技
摇滚侠19 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记