1

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

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 来自哪里?

PS 表被抽真空、分析和重新索引。

4

2 回答 2

2

您应该看看数据库物理存储是如何组织的,尤其是在页面布局上。

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

  • 页头,24 字节;
  • 元组头,27 字节;
  • “隐形”元组版本;
  • 预留空闲空间,根据表的Storage Parameters
  • NULL指标阵列;
  • (可能错过了更多的东西)。

主要版本之间的物理存储布局会发生变化,这就是您必须执行完整转储/恢复的原因。在最近的版本pg_upgrade中对这个过程有很大帮​​助。

于 2012-07-03T08:53:23.777 回答
0

你做了一个 VACUUM FULL 还是CLUSTER?如果没有,未使用的空间仍然专用于该表和索引。这些语句重写表,没有 FULL 的 VACUUM 不会进行重写。

于 2012-07-03T08:17:33.713 回答