postgres 9.2表大小与pg_total_relation_size

时间:2013-03-25 10:32:18

标签: postgresql

我按照以下方式处理一个包含~10 ^ 7行的表:取最后N行,以某种方式更新它们,然后删除,然后删除vacuum表。最后,我对pg_total_relation_size进行了查询。循环重复直到桌子结束。每次迭代持续几秒钟。除了上面提到的以外,对此表没有任何其他查询。问题是我得到了相同的表大小结果。它几乎每隔几个小时就会改变一次。

所以问题是 - postgres是存储表大小的某个地方还是每次调用函数时都计算它?即,尽管处理过,我的表格大小是否真的保持不变?

1 个答案:

答案 0 :(得分:3)

尽管您正在执行DELETEVACUUM,但您的表确实在磁盘上保持相同的大小。根据{{​​3}},普通VACUUM只会通过截断文件末尾的空闲空间而不重新排列实时行来向操作系统释放空间。

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

Pg不仅仅给出这个空间的另一个原因是,当它是一个连续的块时,它只能给操作系统提供空间,直到文件末尾没有可见的行。这不会发生太多,所以在实践中Pg需要移动一些行来压缩表并允许它在末尾释放空间,有点像文件系统上的碎片整理。这是一个低效且缓慢的过程,可以反直觉地使表格访问速度变慢而不是更快,因此这并不总是一个好主意。

如果你的关系大部分但并非完全是空的,那么值得做VACUUM FULL(Pg 9.0及以上)或CLUSTER(所有版本)以释放空间。如果您希望重新填充表格,这通常会适得其反;实际上,保持原样更好。

(就我所说的“实时”和“可见”这样的术语而言,请参阅the documentation on VACUUM,这将有助于您了解Pg的表格组织。)

就我个人而言,我会跳过手册VACUUM。如果需要,请打开autovacuum。如果您确实需要,可以考虑对表进行分区,按分区处理它,并在处理完每个分区时TRUNCATE