PostgreSQL查看表和数据大小的方法(pg_relation_size与pg_total_relation_size)

PostgreSQL查看表和数据大小的方法


想看哪张表占了多少磁盘空间,别只信pgAdmin里那串估算数字,直接查系统函数最准。之前做过一次数据归档,要把大表挑出来迁走,起初用information_schema那套加起来的数和实际差出两倍多,后来换成pg_relation_size才对上。

三个函数各管什么

pg_relation_size('表名')只返回表本身的数据块大小,不含索引、不含toast。pg_total_relation_size('表名')把表+索引+toast全算进去,这才是这张表真正吃掉的空间。pg_indexes_size('表名')单独看索引占了多少,定位「索引比表还大」这种反常最有用。这三个函数从PostgreSQL 8.1(2005年发布)那代起就在,到PostgreSQL 13.4、14.2、15.3行为一模一样。

换算成MB和GB

函数返回的是字节数,直接看不直观,除一下就行:

SELECT pg_size_pretty(pg_total_relation_size('your_table'));

pg_size_pretty会把字节自动转成KB、MB、GB,人读着舒服。要拿数字做排序或阈值判断,就别用pretty,自己除1024:pg_total_relation_size('t')/1024/1024得到MB。见过有人拿pretty出来的字符串去比大小,结果'1024MB'和'1GB'排错了顺序,就是没转成数字。

一次性列出所有大表

要按占用从大到小把全库表排出来,pg_class配合上面那几个函数:

SELECT relname, pg_total_relation_size(oid)/1024/1024 AS mb FROM pg_class WHERE relkind='r' ORDER BY mb DESC LIMIT 20;

relkind='r'过滤掉索引和视图,只留普通表。之前那次归档就靠这条把几十张表里最胖的5张挑出来,省了一半磁盘。实际跑的时候把LIMIT调大一点先全量看一眼。

库级和表级别搞混

pg_database_size('库名')看整个库占多少;pg_table_size('表名')和pg_total的区别是它含toast但不含索引。这几个名字长得很像,记混了会算错。toast是PostgreSQL 8.4(2009年随8.4落地)才正式稳定下来的机制,8.3(及更早的版本)大字段走的是旧方式,但现在基本碰不到那么老的库了。

日常巡检落一条就够。

最常用的就是直接看单表:

SELECT pg_size_pretty(pg_total_relation_size('your_table')) AS total;