2017-10-10 58 views
2

每天我從大表中刪除成千上萬條記錄,然後進行一些計算(使用新數據)並替換之前刪除的每條記錄。我認爲經常做vacuum tbl會做到這一點。我知道它不會將磁盤空間返回到服務器,但是(因爲pg文檔)我以爲因爲我插入的記錄數量與我刪除的記錄數量相同,所以我不會丟失任何/多少磁盤空間。但是,在將表移動到不同的名稱空間之後(出於不相關的原因),該表從117GB變爲44GB!所以......「替換插入」的最佳磁盤保存策略

有沒有更好的策略比這使我的表不臃腫:

delete from tbl where ...etc... -- hundreds of thousands of rows removed 
insert into tbl (...etc...) values (...etc...) -- hundreds of thousands of rows added back (fresh calcs) 

.. repeat the above about 10 times a day ... 

vacuum tbl 

https://www.postgresql.org/docs/9.6/static/sql-vacuum.html

的PostgreSQL 9.6

我實際上沒有減少表的大小是我的答案在這裏: integer out of range and remaining disk space too small to convert id to bigint and other solutions

編輯1: 缺點vacuum full對我來說太侷限了。我正在全天候處理東西,所以我不能擁有這樣的鎖,並且我的可用磁盤空間在任何時間點都非常有限。試圖以更好的方式來解決這個問題。

+0

沒有什麼東西是絕對的「最好的」。根據某些特定標準,某物可能比其他物品更好。 'VACUUM FULL'可以幫助您壓縮數據,從而節省CPU/IO和鎖的開銷。 – zerkms

+0

@zerkms - 請參閱我的編輯1.謝謝! – mountainclimber

回答

2

您在尋找的是「死腔平衡」,我喜歡稱之爲「死腔平衡」。如果你說了1M行並且想要刪除並替換100k行,那麼你可以用不同的方式來完成。假設您刪除100k,並立即插入100k。數據庫沒有時間抽空那些舊的死行,所以現在你的1M行表中有100k個死行。在接下來的24小時內,真空將會啓動並將它們標記爲死亡,下一次刪除/插入時,您將創建100k以上的死行,然後重用(大部分)前100k死行。您的1M行表現在再次有大約10萬行死循環,下次將重用,等等。

你想達到你的刪除/插入(或更新)和真空正在創建/收回死元組的速度均勻的點。

+0

除了真空滿,在刪除之後和插入之前進行吸塵可能會有所幫助......再次感謝! – mountainclimber

+1

是手動真空吸塵器可以非常有效。但要注意的是,手動吸塵器默認沒有「寒意」。即它不會等待系統正常工作,它只會在真空延遲爲0的情況下全速運行。您可以通過alter database或postgresql.conf等設置vacuum_cost_delay,或者通過設置vacuum_cost_delay = 5ms等設置此會話。由於延遲了成本,速度會變慢,但不會很難打敗IO子系統,因此其他進程仍然可以開展工作。 –

+0

我會這樣做的!沒有意識到在手動/程序中有更多的命中。再次感謝! – mountainclimber