CLUSTER
CLUSTER — 根据一个索引对某个表进行聚簇
大纲
CLUSTERindexnameONtablename
输入
indexname一个索引的名称。
table一个表的名称(可以有模式限定)。
输出
CLUSTER聚簇已成功完成。
描述
CLUSTER指示
PostgreSQL基于
indexname所指定的索引,对
table所指定的表进行聚簇。该索引必须已经定义在
tablename上。
当一个表被聚簇时,它会基于索引信息被物理地重新排序。聚簇是一次性操作:当表随后被更新时,这些更改不会被聚簇。也就是说,系统不会尝试按照索引顺序存储新的或更新过的元组。如果需要,可以通过再次发出该命令来周期性地重新聚簇。
注意
如果你在表中随机访问单个行,数据在堆表中的实际顺序并不重要。但如果你倾向于比其他数据更常访问某些数据,并且有一个索引把它们聚集在一起,使用CLUSTER会带来好处。
CLUSTER有帮助的另一个场合是使用索引从一个表中取出多行时。如果你从一个表中请求某个索引值范围,或者一个有多行匹配的单个索引值,CLUSTER会有帮助,因为一旦索引识别出第一行匹配所在的堆页,所有其他匹配的行很可能已经在同一个堆页上,这样就节省了磁盘访问并加快了查询。
在聚簇操作期间,会创建表的一个临时副本,其中按索引顺序包含表数据。表上每个索引的临时副本也会被创建。因此,你需要的空闲磁盘空间至少等于表大小与索引大小之和。
CLUSTER 保留 GRANT、继承、索引、外键以及关于表的其他附属信息。
因为优化器会记录关于表排序的统计信息,建议在新聚簇的表上运行ANALYZE。否则,优化器可能会做出糟糕的查询计划选择。
还有另一种聚簇数据的方法。CLUSTER命令使用你指定的索引的顺序对原表重新排序。在大表上这可能很慢,因为行是按索引顺序从堆中取出的,如果堆表是无序的,各项就散布在随机页面上,因此每移动一行就要检索一个磁盘页。(PostgreSQL有缓存,但大表的大部分放不进缓存。)聚簇一个表的另一种方法是使用
SELECTcolumnlistINTO TABLEnewtableFROMtableORDER BYcolumnlist
它在 ORDER BY 子句中使用
PostgreSQL的排序代码来产生想要的顺序;对于无序数据,这通常比索引扫描快得多。然后你删除旧表,使用
ALTER TABLE...RENAME把
newtable改名为旧名称,并重建该表的索引。不过,这种方法不保留 OID、约束、外键关系、已授予的权限以及表的其他附属属性——所有这些项都必须手动重建。
用法
基于其 ID 属性聚簇 employees 关系:
CLUSTER emp_ind ON emp;
兼容性
SQL92
SQL92 中没有CLUSTER语句。