【问题标题】:Wrong (?) Size of PostgreSQL table错误 (?) PostgreSQL 表的大小
【发布时间】:2012-07-03 07:29:24
【问题描述】:

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

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

附:表格被抽真空、分析和重新索引。

【问题讨论】:

    标签: postgresql storage vacuum


    【解决方案1】:

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

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

    • 页眉,24字节;
    • 元组头,27 字节;
    • “不可见”元组版本;
    • 预留的空闲空间,根据表的Storage Parameters
    • NULL指标数组;
    • (可能还漏掉了一些东西)。

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

    【讨论】:

    • 您错过了空指标数组。 (OP 的 4 列可以为空)我不知道对齐:就个人而言,我会选择对齐并将短裤填充到 4 字节边界。
    • 非常感谢!我只是在考虑如何解决它,因为我假设我的应用程序将插入 aprox。每天 2 到 5 百万条记录(!):D 我当然会汇总这个,但有一段时间我需要存储行数据。有什么想法吗? :) 谢谢!
    • @user1414355,您需要考虑对表进行分区,因为您很快就会遇到性能问题。 This answer 是一个例子,更多细节是in docs
    • 谢谢!现在我正在考虑使用所有服务器迁移到亚马逊云,所以我会认真对待这个解决方案。再次感谢队友:)
    • @user1414355,不客气!接受答案以关闭它们是一种很好的做法。
    【解决方案2】:

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

    【讨论】:

    • 我做了一个 VACUUM FULL。现在我只是添加到这个表中,现在不删除任何东西。
    猜你喜欢
    • 2022-01-24
    • 2020-09-26
    • 2016-01-03
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多