CLUSTER之后需要REINDEX吗?


12

我正在考虑使用CLUSTER通过索引对表重新排序。我知道表数据的重新创建使所有现有索引要么过时,要么变得毫无用处。我已经看到一些迹象表明在集群之后需要REINDEX。我发现其他引用表明CLUSTER 执行了REINDEX。在官方文档说,一切尽在不言中约REINDEX是集群的一部分或需要(虽然它确实表明集群运行后分析),

任何人都可以明确地(例如,对官方文档进行某种程度的引用)说出在CLUSTER之后是否需要REINDEX吗?


2
我认为没有必要。cluster重新定位行,因此无论如何都必须更新索引信息。
a_horse_with_no_name 2013年

是的,但是在我发现的一半讨论中,该理论导致该索引膨胀。
TREE

Answers:


12

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

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

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

如果您一直在讨论暗示CLUSTER膨胀的索引,那可能是那些认为它CLUSTER像9.0之前版本那样工作的人VACUUM FULL。您可能还会看到和误读有关由旧VACUUM FULL实现引起的索引膨胀的讨论,并提出CLUSTER替代建议。

在文档中暗含

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

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


1
您有CLUSTER取代索引的参考吗?
TREE

1
@TREE已添加。文档并没有明确告诉您临时表和索引会替换原始文档,但是如果您实际查看的是CLUSTER之前/之后的数据目录,或者您检查源代码,就会发现情况确实如此。
Craig Ringer 2013年

我已经对此进行了测试,并且至少在我的测试方案中,索引文件的大​​小减小了。但这只是一种情况,可能会有许多变量影响行为(索引数,磁盘总大小等),所以我不能相信一个简单的测试。
TREE

1
@TREE为了绝对确定在所有可能情况下的行为,您需要阅读源代码。我可以告诉你的是,我不知道在任何情况下CLUSTER不能改写的指标,实际文件的审查中base/会清楚地显示新relfilenode秒。似乎您正在担心尚未出现的问题。
Craig Ringer

8

我对此使用a_horse_with_no_name:您不需要重新创建索引。除了CLUSTER文档没有提及之外,我们也可以进一步查询该REINDEX页面:

在几种情况下可以使用REINDEX:

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

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

  • 您已经更改了索引的存储参数(例如fillfactor),并希望确保所做的更改已完全生效。

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

显然,CLUSTER不属于任何一种情况。

CLUSTER文档中有一句话:

[在集群期间]还将创建表上每个索引的临时副本。

这表明,就像表本身一样,索引也将在处理过程中重新排序-这种方式使重新索引无用。


该建议肯定存在,测试似乎证实了这一建议。如果文档实际上(永久地)重新创建了索引,我会更好地依靠这种行为。
TREE

2
我在这里看到文档补丁的内容。该手册应更明确地说明如何重新创建索引。
Erwin Brandstetter

我在这一点上的怀疑是,开发人员不想正式记录这种行为,因为他们不想永久地与该实现联系在一起。
TREE

@TREE在版本之间有许多功能更改,而文档也相应地(主要是在)更改。大概规格也改变了:),所以我看不到任何领带。
dezso 2013年

@dezso是的,但是他们不愿意删除已记录的功能。考虑到一般文档的质量,我仍然认为忽略此行为是有意的。
TREE

5

在“ 恢复磁盘空间”部分中找到了参考。

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


-3

分析所有答案,我认为正确的方法是在群集之前重新编制索引。由于文档没有说明集群是否进行了重新索引,并且仅指示索引的副本(是否有序),因此我认为建立索引的索引将导致更好的集群表。之后,分析将完成工作。除非群集和/或重新索引不能释放死元组,否则,完全充满真空似乎是没有用的。


正如我在接受的答案中提到的那样,文档确实说将重建索引,只是不在有关CLUSTER命令的页面上。
TREE

而且两者CLUSTERVACUUM FULL产生一个全新的物理表-那里根本就不能算是后,任何死角。在操作结束之前,旧副本使用的空间将被释放。
dezso

确实。它重新创建表和所有索引。但是我对集群用来重新排序表的索引有疑问。它将首先被重新索引还是将被用于按原样对表重新排序?然后重新创建索引?因为有问题的索引可能会引起一些问题...
Aislan Luiz Wendling 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.