postgres 9.2表大小与pg_total_relation_size

问题描述:

我用〜10^7行处理一个表的方式如下:取最后N行,以某种方式更新它们,然后删除表vacuum表。最后,我询问了pg_total_relation_size。循环重复,直到表格结束。每次迭代持续几秒钟。除了上面提到的以外,没有任何其他查询。问题是我得到了相同的表格大小的结果。它几个小时变化一次。postgres 9.2表大小与pg_total_relation_size

所以问题是 - postgres是否存储表的大小,或者每次调用函数时都计算它?也就是说,尽管进行了处理,我的桌子尺寸是否真的保持不变?

+0

PostgreSQL版本?在各个版本中'VACUUM'已经发生了很大的变化。 **问题**中始终提及您的PostgreSQL版本。 – 2013-03-25 10:38:40

+0

@克雷格抱歉,已完成 – zapadlo 2013-03-25 10:40:16

尽管您正在使用DELETEVACUUM,但您的表格确实在磁盘上保持相同大小。根据the documentation on VACUUM,普通VACUUM只能通过从文件末尾截断可用空间而不重新安排实时行来释放回操作系统的空间。

该空间仍然是“免费”的,因为PostgreSQL可以将其重新用于其他新行。重复使用PostgreSQL没有给OS返回的空间要比用新空间扩展关系要快得多,所以这通常是可取的。

Pg不只是给这个空间回来的另一个原因是,它只能给操作系统空间时,当它是一个连续的块,没有可见的行直到文件结束。这种情况并没有发生,所以实际上Pg需要移动一些行来压缩表格,并允许它最终释放空间,就像文件系统上的碎片整理一样。这是一个效率低下且缓慢的过程,它可以直观地使表访问速度更慢,而不是更快,所以它并不总是一个好主意。

如果您有一个大多数但不是完全空的关系,则可以使用VACUUM FULL(页面9.0及更高版本)或CLUSTER(所有版本)来释放空间。如果你想补充桌子,这往往会适得其反。实际上离开它实际上更好。

(对于我通过类似的术语表示“活”和“看得见的”看documentation on MVCC这将有助于你了解PG的表组织。)

个人而言,我会跳过手动VACUUM你的情况。如果需要的话,打开自动清理。如果您真的需要,可以考虑对表格进行分区,在完成处理后按分区对每个分区进行分区处理。

+0

我可以假设第(N + 1)行比第N个更接近文件末尾吗?该表用于日志,因此没有删除或更新的行。所描述的处理是在上个月的分区上进行的。 – zapadlo 2013-03-25 10:44:27

+0

@Zapadlo不,你不能可靠地假设。如果表格在重新填充之前是“TRUNCATE”d,通常是* true,但不是您可以依赖的东西。即使是这样,试图从表格末尾开始工作的成本可能会高于任何收益。为什么?你是否真的需要腾出空间,或者如果你缩小桌子,你是否希望它更快? – 2013-03-25 10:47:37

+0

@Zapadlo对于真正只附加表格,只要表格被截断,只要不能保证,就应该合理可靠。 – 2013-03-25 10:53:33