CLUSTER 之后是否需要 REINDEX?

TRE*_*REE 12 postgresql

我正在考虑使用 CLUSTER 按索引重新排序表。我知道这种表数据的重新创建会使所有现有的索引膨胀或无用。我已经看到一些迹象表明在 CLUSTER 之后需要 REINDEX。我发现其他参考资料表明 CLUSTER执行REINDEX。在官方文档说,一切尽在不言中约REINDEX是集群的一部分或需要(虽然它确实表明集群运行后分析),

任何人都可以明确地(即对官方文档进行某种参考)说在 CLUSTER 之后是否需要 REINDEX?

Cra*_*ger 15

您不需要重新索引,因为CLUSTER它可以有效地为您完成。

更具体地说,CLUSTER锁定源表然后根据目标索引创建它的新副本。它在新副本上创建索引,然后用新表替换旧表和索引。

请注意,这VACUUM FULL在 9.0+ 中也是如此。

如果您一直看到讨论表明CLUSTERbloat 索引,那可能是有人假设它CLUSTER像 pre-9.0 一样工作VACUUM FULL。您可能还看到并误读了一些讨论,这些讨论提到了由旧VACUUM FULL实现引起的索引膨胀,并建议将其CLUSTER作为替代方案

在文档中暗示

创建表的临时副本,其中包含按索引顺序排列的表数据。表上每个索引的临时副本也被创建。因此,您需要磁盘上的可用空间至少等于表大小和索引大小的总和

它没有说但应该说的是那些临时副本然后替换原始 table。(大胆的我的)。


dez*_*zso 8

我与 a_horse_with_no_name 在一起:您不需要重新创建索引。除了CLUSTER文档没有提到它,我们也可以进一步查阅该REINDEX页面:

有几种使用 REINDEX 的场景:

  • 索引已损坏,不再包含有效数据。尽管理论上这永远不会发生,但实际上索引可能会由于软件错误或硬件故障而损坏。REINDEX 提供了一种恢复方法。

  • 索引变得“臃肿”,即它包含许多空或接近空的页面。在某些不常见的访问模式下,PostgreSQL 中的 B 树索引可能会发生这种情况。REINDEX 提供了一种减少索引空间消耗的方法,即在没有死页的情况下写入新版本的索引。有关更多信息,请参阅第 23.2 节。

  • 您已更改索引的存储参数(例如填充因子),并希望确保更改已完全生效。

  • 带有 CONCURRENTLY 选项的索引构建失败,留下“无效”索引。这样的索引是无用的,但使用 REINDEX 重建它们会很方便。请注意,REINDEX 不会执行并发构建。要在不干扰生产的情况下构建索引,您应该删除索引并重新发出 CREATE INDEX CONCURRENTLY 命令。

显然,CLUSTER不属于这些情况中的任何一种。

CLUSTER文档中有一个小句子:

[while clustering] 表上每个索引的临时副本也被创建。

这表明就像表本身一样,索引也会在此过程中重新排序——这样重新索引就无用了。

  • 我在这里看到了文档补丁的内容。手册应该更明确地重新创建索引。 (2认同)

TRE*_*REE 6

恢复磁盘空间部分找到了一个参考。

如果您有这样的表并且需要回收它占用的多余磁盘空间,则需要使用 VACUUM FULL,或者CLUSTER或 ALTER TABLE 的表重写变体之一。这些命令重写表的整个新副本为其构建新索引