错误的(?)PostgreSQL表的大小

时间:2012-07-03 07:29:24

标签: postgresql storage vacuum

我有一个包含列和约束的表:

height smallint,
length smallint,
diameter smallint,
volume integer,
idsensorfragments integer,
CONSTRAINT sensorstats_idsensorfragments_fkey FOREIGN KEY (idsensorfragments)
  REFERENCES sensorfragments (idsensorfragments) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE

(没有主键)。目前有28 978 112条记录,但在我看来,这张桌子的大小太多了。

查询结果:

select pg_size_pretty(pg_total_relation_size('sensorstats')), pg_size_pretty(pg_relation_size('sensorstats'))

是:

"1849 MB";"1226 MB"

idsensorfragments 列只有一个索引。使用简单的数学运算,您可以看到一条记录需要~66,7 B(?!?!)。谁能解释一下这个数字来自哪里?

5列= 2 + 2 + 2 + 4 + 4 = 14字节。我有一个索引,没有主键。每条记录额外增加50B?

P.S。将表抽真空,分析并重新索引。

2 个答案:

答案 0 :(得分:2)

您应该了解Database Physical Storage的组织方式,尤其是Page Layout

PostgreSQL为每个元组(行)和每个页面保留了一堆额外的字段。元组保存在Pages中,因为Page是数据库操作的项目,通常为8192字节。额外的空间使用来自:

  • PageHeader,24个字节;
  • Tupleheader,27个字节;
  • “隐形”元组版本;
  • 保留的可用空间,根据表格的Storage Parameters;
  • NULL指标数组;
  • (可能错过了更多内容)。

主要版本之间的物理存储布局发生变化,这就是您必须执行完全转储/恢复的原因。在最近的版本pg_upgrade中,这个过程非常有用。

答案 1 :(得分:0)

你做过VACUUM FULL还是CLUSTER?如果不是,则未使用的空间仍专用于此表和索引。这些语句重写表,没有FULL的VACUUM不会重写。