2017-10-10 56 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