CLUSTER 指示PostgreSQL 基于索引 indexname 的度量对表 table 进行存储建簇. 索引必须已经在表 tablename. 上定义了.
当对一个表建簇后,该表的物理存储将基于索引信息进行. 建簇是一次性操作:也就是说,当表随后被更新后,改变的内容不会建簇. 也就是说,系统不会试图按照索引顺序对更新过的记录重新建簇. 如果需要,可以通过周期性地手工执行该命令的方法重建簇.
在对一个表建簇之后,PostgreSQL 会记忆在哪个索引上建立的簇。如果调用 CLUSTER tablename, 那么就在表以前建簇的同一个索引上建簇。
一个简单的 CLUSTER 将对数据库里属于调用者的所有表进行 建簇,并且将保存建簇信息。这种形式的 CLUSTER 不能从一个 事务或者函数内部调用。
如果你只是随机的访问表中的行, 那么在堆表中的数据的实际存储顺序是无关紧要的. 但是,如果你对某些数据的访问多于其他数据, 而且有一个索引将这些数据分组,那你就将从 使用 CLUSTER 中获益.
另一个CLUSTER 很有帮助的例子是当你用索引从一个表中取出几个记录时. 如果你从一个表中请求一定索引范围的值, 或者是一个索引过的值对应多行, CLUSTER 也会有助于应用, 因为如果索引标识出第一匹配行所在的堆存储页,所有 其他行也可能已经在同一堆存储页里了, 这样便节省了磁盘访问的时间,加速了查询.
在这个建簇的操作过程中,系统先创建一个按照索引顺序建立的表的临时拷贝。 同时也建立表上的每个索引的临时拷贝。因此,你需要磁盘上有足够的剩余空间, 至少是表大小和索引大小的和。
CLUSTER保留 GRANT,继承,索引,外键,以及表的其它辅助性信息。
因为 CLUSTER 记忆建簇信息,我们可以在第一次的时候 手工对表进行建簇,然后设置一个类似 VACUUM 的时间, 这样我们就可以周期地自动对表进行建簇了。
因为优化器记录着有关表的排序的统计,所以我们建议在新近建簇的表上 运行 ANALYZE。否则,优化器可能会选择很差劲的查询规划。
还有一种建簇的方法。 CLUSTER 命令将原表按你声明的索引重新排列. 这个动作在操作大表时可能会很慢, 因为每一行都从堆存储页里按索引顺序取出,如果存储页表没有排序, 整个表是随机存放在各个页面的,因而移动的每一行都要进行一次磁盘页面操作. PostgreSQL 有一个缓冲, 但一个大表的主体是不可能都放到缓冲去的. 另外一种对表建簇的方法是
SELECT columnlist INTO TABLE newtable FROM table ORDER BY columnlist
这个用法使用PostgreSQL 排序的代码 ORDER BY 来创建一个需要的顺序,在对未排序的数据操作时通常速度 比索引扫描快得多. 然后你可以删除旧表,用 ALTER TABLE...RENAME将 newtable 改成旧表名, 并且重建该表所有索引.但是,这个方法不保留 OID,约束,外键关系, 赋予的权限,以及表的其它附属的属性 ---- 所有这些属性都必须手工重建。