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

PostgreSQL中重新排序列对记录大小的影响是什么?,postgresql,vacuum,Postgresql,Vacuum,由于Postgres只能在表的末尾添加列,因此我通过在表的末尾添加新列,将它们设置为与现有列相等,然后删除原始列来重新排序 那么,PostgreSQL如何处理被删除列释放的内存呢?它是否会自动重复使用内存,因此单个记录消耗的空间量与以前相同?但这需要重新写入整个表,因此为了避免这种情况,它是否只是在每条记录中保留一堆空白?: DROP COLUMN表单不会从物理上删除该列,而只是使其对SQL操作不可见。表中的后续插入和更新操作将为列存储空值。因此,删除列很快,但不会立即减少表的磁盘大小,因为删除

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

那么,PostgreSQL如何处理被删除列释放的内存呢?它是否会自动重复使用内存,因此单个记录消耗的空间量与以前相同?但这需要重新写入整个表,因此为了避免这种情况,它是否只是在每条记录中保留一堆空白?

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

您需要先进行
群集
,然后进行
真空填充
,以回收空间。

为什么要“重新排序”?SQL中没有顺序,没有意义。如果您需要一个固定的顺序,告诉您的查询您需要什么顺序,或者使用视图,这就是视图的用途

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

您当前的方法将破坏整体性能(表锁),必须重新创建索引,统计数据将被丢弃,等等。最后,您将面临与allready相同的情况。那么为什么要这么做呢?

这个问题已经很老了,但由于两个答案都是错误的或误导性的,我将添加另一个

当更新一行时,Postgres写入一个新的行版本,并且在运行的事务无法再看到它之后,
VACUUM
最终会删除旧的行版本

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

在您的情况下,由于您更新了每一行,因此表的大小将增加一倍(从其最小大小)。建议运行
VACUUM FULL
CLUSTER
将膨胀返回系统。
两者都在桌子上有一个独占锁。如果这干扰了并发访问,请考虑,它可以在没有排他锁的情况下执行同样的操作。 澄清一下:运行
CLUSTER
完全回收空间

更多详情:


我本以为会出现这种情况。我喜欢我的专栏的顺序对像我这样的人类来说是有意义的。只要它不占用太多的磁盘空间(真空满后就不会占用)。只是个人喜好。:)您不应该依赖隐式列排序,就像在没有ORDERBY的查询中不应该依赖隐式行排序一样。这是否意味着您的应用程序使用SELECT*和INSERT到表值,而不使用字段名?因为那只是自找麻烦。如果您需要特定的列顺序,请使用该顺序创建一个视图。我需要重新排序,因为对某些列进行分组更容易!我真不敢相信像这样的基础课程在博士后是不受支持的。。。。当然,我不依赖于表中列的顺序,但在设计数据库时,这更容易!为什么这些linux的书呆子们不明白这一点?!现在人们使用GUI!现在是2011年!这个答案在几点上是不正确的。列的物理顺序有许多含义。不仅在选择*。。对物理磁盘空间(类型对齐)和性能有副作用-即使在大多数情况下并不重要。postgres团队拥有对待办事项列表中的列进行重新排序的功能,他们承认这很有用。OP表示这是一种罕见的操作,对性能的担忧是错误的。仅仅因为有很多错误的理由对列进行重新排序,并不意味着没有好的理由。声称“SQL中没有顺序”是完全错误的。真空填充只会在更新每一行时回收空间,它会在完全死行之后进行清理,而不是在其他好行中清理死列。由于设置新列的更新必须在执行删除操作之前进行,因此现在过时的列占用的空间不会被它回收。只有行的旧的原始副本将被清除。除了完全更新之外,您还可以执行集群(在PostgreSQL 8.3或更高版本中)或创建表的一个全新副本(类似于创建表AS)并重新排列名称,以实际消除死列占用的空间。@Summer:
CLUSTER
重写整个表(加上索引),从而完美地优化它<代码>真空满在
集群
之后是冗余的。您可能需要运行
分析
。此答案不正确(报价除外)。我补充了一个答案来澄清。