PostgreSQL中重新排序列的记录大小有什么影响?

时间:2010-04-08 16:09:32

标签: postgresql vacuum

由于Postgres只能在表的末尾添加列,我最后通过在表的末尾添加新列,将它们设置为等于现有列,然后删除原始列来重新排序。

那么,PostgreSQL对被删除列释放的内存做了什么?它是否会自动重复使用内存,因此单个记录会占用与以前相同的空间量?但是这需要重写整个表格,所以为了避免这种情况,它是否只是在每个记录中留下了一堆空白?

3 个答案:

答案 0 :(得分:1)

来自docs

  

DROP COLUMN表单不会以物理方式删除该列,而只是使其对SQL操作不可见。表中的后续插入和更新操作将为列存储空值。因此,删除列很快,但不会立即减少表的磁盘大小,因为已删除列所占用的空间不会被回收。随着现有行的更新,该空间将随着时间的推移而被回收。

您需要执行CLUSTER后跟VACUUM FULL来回收空间。

答案 1 :(得分:1)

你为什么“重新排序”? SQL中没有顺序,它没有出现。如果您需要固定订单,请告诉您的查询您需要的订单或使用视图,这就是查看的内容。

真空后将再次使用磁盘空间,auto_vacuum将完成这项工作。除非您禁用此过程。

您当前的方法会破坏整体性能(表锁),索引必须重新创建,统计数据会下降等等。最后,您最终会得到您已经拥有的相同情况。那么为什么努力?

答案 2 :(得分:1)

问题是陈旧的,但由于两个答案都是错误的或误导性的,我会再添加一个。

更新行时,Postgres会写一个新的行版本,而旧的版本最终会被VACUUM删除,因为没有正在运行的事务可以再看到它。

普通VACUUM不会将包含该表的物理文件的磁盘空间返回给系统,除非它在表的物理端找到完全死的或空的块。您需要运行VACUUM FULLCLUSTER来积极地压缩表并将多余的空间返回给系统。这在正常操作中通常不是所希望的。 Postgres可以重复使用死元组将新行版本保留在同一数据页面上,这有利于提高性能。

在您的情况下,由于您更新了每一行,因此表的大小会加倍(从其最小大小开始)。建议运行VACUUM FULL CLUSTER将膨胀返回系统。
两者都采取独家锁定在桌子上。如果这会干扰并发访问,请考虑pg_repack,这可以在没有排他锁的情况下执行相同操作。

澄清:运行CLUSTER完全回收空间。 No VACUUM FULL is needed after CLUSTER (and vice versa).

更多详情: