postgresql查表大小应使用pg_total_relation_size(),它返回包含数据、索引和toast的总字节数,避免仅用pg_relation_size()导致漏计索引而偏小50%以上;结果需转换为mb:round(pg_total_relation_size('table_name')::numeric/1024/1024,2)。

查 PostgreSQL 表大小用 pg_total_relation_size()
PostgreSQL 不直接暴露“表占多少 MB”在系统视图里,得靠函数算。最常用的是 pg_total_relation_size(),它返回字节数,包含数据、索引、TOAST 表全部加起来的总大小。
常见错误是只查 pg_relation_size() —— 它只算主数据页,漏掉索引,结果可能偏小 50% 以上。
-
pg_total_relation_size('users'):查单表总大小(含索引) -
pg_total_relation_size('users', true):加true表示包含子分区(如果表是分区表) - 结果是字节,记得除以
1024^2转 MB:round(pg_total_relation_size('users')::numeric / 1024 / 1024, 2)
查 MySQL 表大小看 information_schema.TABLES
MySQL 把大小存在 information_schema.TABLES 里,但要注意字段含义:
-
DATA_LENGTH:数据部分字节数(.ibd 文件主体) -
INDEX_LENGTH:索引部分字节数 -
DATA_FREE:已分配但未使用的空间(常被误认为“碎片”,其实只是预分配) - 真正“占用磁盘”的是
DATA_LENGTH + INDEX_LENGTH,不是DATA_FREE
执行示例:
SELECT table_name, round((data_length + index_length) / 1024 / 1024, 2) AS size_mb FROM information_schema.TABLES WHERE table_schema = 'mydb' AND table_name = 'orders';
SQL Server 查 sys.dm_db_partition_stats 更准
SQL Server 的 sp_spaceused 看起来方便,但它是基于元数据估算,有时滞后;真要准,得查动态管理视图 sys.dm_db_partition_stats。
- 每行对应一个分区,
reserved_page_count是总保留页数,used_page_count是实际使用页数 - 一页 = 8KB,所以真实占用 ≈
used_page_count * 8 / 1024.0(MB) - 必须 JOIN
sys.tables和sys.schemas才能按表名过滤,否则只看到 object_id - 注意:
lob_used_page_count单独统计大对象(如TEXT、XML),不包含在used_page_count里,要加总
跨数据库查大小时最容易忽略的点
不同数据库对“大小”的定义差异很大,直接对比会出错:
- PostgreSQL 的
pg_total_relation_size()包 TOAST,MySQL 的DATA_LENGTH不含二级索引以外的额外结构 - SQL Server 的
used_page_count是运行时统计,需DBCC UPDATEUSAGE同步才准;而 PostgreSQL 函数每次都是实时计算 - 所有方法都不反映 WAL 日志、备份文件、临时表空间——这些不在“表本身”范畴内,但占磁盘
如果你在做容量规划,别只盯一个数字;先确认你到底想管哪块空间:是当前可释放的?还是未来半年增长预期?还是磁盘告警阈值依据?问题不同,查的表和解释方式就不同。










