结构界面查不到实时行数是因为默认关闭统计更新,pg_class.reltuples仅为估算值;需手动执行vacuum刷新,或用count(*)获取精确值(小表可采样),表大小推荐用pg_total_relation_size()。
结构界面里查不到实时行数?那是默认关了统计
PostgreSQL 的 pg_class 视图里存着表的估算行数(reltuples),但结构界面(比如 pgAdmin、DBeaver 的“Properties”或“Statistics”页)显示的通常是上次 VACUUM 或 ANALYZE 之后的快照值,不是实时的。想看到接近实时的行数和大小,得主动触发统计刷新,或者绕过缓存直接查系统表。
用 pg_total_relation_size() 看真实磁盘占用
这个函数返回的是表+索引+TOAST 的总字节数,比结构界面里只显示“表大小”的数值更准。注意它不包含 FSM/VISIBILITY MAP 文件,但对绝大多数场景已足够。
-
pg_total_relation_size('users')—— 返回整张表(含索引)字节数 -
pg_relation_size('users')—— 只返回主表数据文件大小(不含索引) - 结果是字节,建议除以 1024.0 再套两层
round(..., 2)转成 KB/MB 更直观 - 如果表名带 schema,必须写成
'public.users',单引号不能少
查实时行数别信 reltuples,用 COUNT(*) 但要防卡死
SELECT reltuples::BIGINT FROM pg_class WHERE relname = 'users' 返回的是优化器用的估算值,可能偏差几十倍。真要精确数字,只能 COUNT(*),但大表会全表扫描、锁等待高、拖慢其他查询。
- 小表(SELECT COUNT(*) FROM users 安全
- 中大表(>100 万):先加
WHERE ctid IN (SELECT ctid FROM users TABLESAMPLE SYSTEM (1))做采样估算,或用扩展pg_stat_rows(需安装) - 千万别在业务高峰期对千万级表跑裸
COUNT(*)—— 会堵住 WAL 写入,连VACUUM都可能被卡住
结构界面的“刷新统计”按钮其实只调 ANALYZE
pgAdmin 点“Refresh Statistics”,本质是执行 ANALYZE users,它更新列分布、空值率、最常见值等,但不会重算 reltuples(那个值由 VACUUM 更新)。所以即使点了刷新,行数还是旧的。
-
ANALYZE不锁表,安全,但改不了行数统计 -
VACUUM才会更新reltuples,但它会获取SHARE UPDATE EXCLUSIVE锁,且耗时长 - 真正想让结构界面数字变新,得手动跑
VACUUM users,不是点按钮 - 如果只是看大小,
VACUUM对pg_total_relation_size()结果没影响——那个函数读的是文件系统,不走统计缓存
表大小基本看 pg_total_relation_size() 就够用,但行数永远是个权衡:要快就信估算,要准就得担风险。没人能一边秒回精确行数,一边不锁表不扫盘。










