2013-03-25 49 views
0

我用〜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

回答

3

儘管您正在使用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