PgSQL中pg_stat_user_tables 和 pg_stat_user_objects参数详解

pg_stat_user_tablespg_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 vacuumanalyze
reltuples bigfloat 表中的行数(尺寸的近似值,基于last vacuumanalyze

注意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 找到一个感兴趣的大对象,然后通过它的 relidrelkind 去更专门的统计视图(如 pg_stat_user_tablespg_statio_user_indexes)中获取其详细性能数据。

相关推荐
❀͜͡傀儡师3 小时前
Docker部署搜索引擎SearXNG
运维·docker·容器·searxng
倔强的石头_3 小时前
Windows系统下KingbaseES数据库保姆级安装教程(附常见问题解决)
数据库
MChine慕青3 小时前
顺序表与单链表:核心原理与实战应用
linux·c语言·开发语言·数据结构·c++·算法·链表
虎头金猫3 小时前
如何在Linux上使用Docker在本地部署开源PDF工具Stirling PDF:StirlingPDF+cpolar让专业操作像在线文档一样简单
linux·运维·ubuntu·docker·pdf·开源·centos
麦兜*3 小时前
MongoDB 常见错误解决方案:从连接失败到主从同步问题
java·数据库·spring boot·redis·mongodb·容器
RestCloud4 小时前
PostgreSQL大表同步优化:如何避免网络和内存瓶颈?
前端·数据库·api
阿里云大数据AI技术4 小时前
淘宝闪购基于Flink&Paimon的Lakehouse生产实践:从实时数仓到湖仓一体化的演进之路
数据库·flink
荣光波比4 小时前
Nginx 实战系列(七)—— Nginx一键安装脚本详解
运维·nginx·自动化·云计算
努力学习的小廉4 小时前
深入了解linux系统—— 线程同步
linux·服务器·数据库·算法