在PostgreSQL 8.4中重新索引之前,是否应该总是进行VACUUM ANALYZE?


8

每天清晨,一个pgAgent作业都会从我的PostgreSQL 8.4数据库中的表B中刷新表A的内容。表A在91列中包含约140k记录,并具有两个索引-一个作为PRIMARY KEY的一部分,另一个在POINT PostGIS几何列上的GIST索引。

为了使过程更快一些,作业将删除几何列上的索引,然后删除表A中的记录并从表B中插入记录,然后重新创建索引。autovacuum守护程序在感觉良好时就可以完成所有工作(大约在十分钟后,通过比较作业状态和表状态的作业完成时间和autovacuum运行时间)。

在所有这些都发生之后,今天早上检查表时,表统计信息告诉我表大小为272MB,TOAST表大小为8192bytes,索引大小为23MB。这似乎很大,所以我在表上发出了REINDEX命令,索引大小降至9832kB。

我的问题是这样的:

为什么当从头开始重新构建索引(或至少是几何列索引)时,REINDEX会明显减少索引的大小?我应该确定在建立索引之前已经对表进行了清理/分析吗?这不是在主键上删除索引的一个因素吗?我想念什么?


1
有什么阻止您升级到9.3的功能吗?否则,我不会记得太多8.4,但是大小可能仅因为表最近没有被分析而有所不同吗?我会检查(如果可能的话)平原后ANALYZE报告的尺寸是否也减小了。
dezso 2014年

@dezso很遗憾,我们无法在不久的将来更新到最新版本。每天刷新一次后,我将在下一个机会尝试重新分析-ANALYZE是否收集有关索引的统计信息?
UrsineWelles 2014年

@deszo发出VACUUM ANALYZE来检查结果,然后REINDEXing可以使索引大小大幅度减少。
UrsineWelles 2014年

或者,在进行升级时,为什么不直接使用当前版本9.4?Postgres 8.4已在2014年达到停产期。自此以来,清理和索引编制已进行了许多次改进。
Erwin Brandstetter,2015年

@ErwinBrandstetter-我们正在这里进行更新...不久,我的同事将更新他们的软件,这将使他们能够升级到Cadcorp SIS 8.0,这又将使我们升级到Postgres(到9.3)。我期待获得清理和索引的奖励!
UrsineWelles

Answers:


3

如果CREATE INDEX语句看到另一个会话持有可能仍对删除的记录感兴趣的活动快照,则它将那些删除的记录包括在新索引中。

同样,如果REINDEX看到另一个会话持有可能仍对删除的记录感兴趣的活动快照,则它将那些删除的记录包括在新索引中。

如果VACUUM看到另一个会话持有可能仍对删除的记录感兴趣的活动快照,则它将这些记录保留在表中。然后只要快照仍然存在,REINDEX或CREATE INDEX也需要将它们带入新索引。

一旦存在快照或不再有任何快照可能看到已删除的行,VACUUM便可以将它们从表中删除。但是无论VACUUM是否已设法将其从功能中删除,CREATE INDEX或REINDEX也可能无法将它们带入新的索引中。

因此,在您的情况下,VACUUM在初始CREATE INDEX和REINDEX之间的作用可能只是占用时间,在此期间,您长时间运行的事务有望自行消失并丢弃干扰的快照。


一定是这样。我将不得不留意此类交易。
UrsineWelles

Postgres 9.3是否需要重新索引?
Munai Das Udasin'7

0

尝试过不同的处理顺序后,似乎确实要在REINDEX指令之前执行VACUUM是减小大小的唯一方法,这可能是因为未空余的空间增加了索引(已删除记录的索引?)。通过使用强制表重写

ALTER TABLE blah ALTER COLUMN whiffle SET DATA TYPE whiffle_type;

它可以清除废弃空间,因此可以做同样的事情。

由于必须在事务外部发出VACUUM命令,因此在过程的中间必须使用VACUUM确实会使流程中断。


您要删除还是截断?您是否在这些索引上将填充因子设置为100?
大卫·奥尔德里奇

嗨@DavidAldridge。我要删除而不是截断。fillfactor是默认设置。
UrsineWelles 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.