在 PostgreSQL 8.4 中重新索引之前应该总是 VACUUM ANALYZE 吗?

Urs*_*les 8 postgresql index postgresql-8.4

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

为了使过程更快一点,作业删除几何列上的索引,然后删除表 A 中的记录并插入表 B 中的记录,然后重新创建索引。这一切都完成了 autovacuum 守护进程在感觉它开始工作时开始工作(在比较作业完成时间和 autovacuum 运行时间的作业统计信息和表统计信息后十分钟左右)。

在这一切发生后,今天早上检查表时,表统计告诉我表大小为 272MB,TOAST 表大小为 8192 字节,索引大小为 23MB。这看起来很大,所以我在表上发出了 REINDEX 命令,索引大小下降到 9832kB。

我的问题是这样的:

当索引(或至少几何列索引)从头开始重新构建时,为什么 REINDEX 明显减少了索引的大小?在建立索引之前,我是否应该确保表已被清空/分析?删除主键上的索引不是其中的一个因素吗?我错过了什么?

jja*_*nes 5

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

类似地,如果 REINDEX 看到另一个会话持有可能仍对已删除记录感兴趣的活动快照,则它将这些已删除记录包含到新索引中。

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

一旦存在或不再有任何可能看到已删除行的快照,则 VACUUM 可能会将它们从表中删除。但是 CREATE INDEX 或 REINDEX 也不能将它们转移到新索引中,无论 VACUUM 是否已经开始将它们从能力中删除。

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