这里是postgre给出的API相关参考,其它数据库原理可以借鉴。
CLUSTER INDEX聚簇索引
CLUSTER indexname ON tablename
CLUSTER tablename
CLUSTER
CLUSTER使DBMS根据indexname指定的索引将tablename表聚集。前提是在这个表中已经有此索引。也就是说要先在一个表中建索引,再根据这个索引使这张表聚集。(注意:不要在hash index上聚簇,这样做是没有意义的,hash本来就是无序的,只是用来快速找到相应数据的位置而已。也就是说一般只在b+树的索引上聚簇)
当一张表执行聚簇索引后,它在物理存储上也就根据索引信息的顺序排序了。索引只是一次执行,它以后并不自动重新进行聚簇,也就是说,当在已经聚簇的表中做修改时DBMS并不自动根据修改过的信息重新排序聚簇。如果需要你可以周期性的显式重新聚簇。
一张表聚簇后,系统会记住它所依据的索引,因此CLUSTER tablename就可以用来方便地实现重新聚簇,完成周期性的聚簇任务。
CLUSTER在没有任何参数的情况下,将重新聚簇这个用户当前所拥有的数据库中所有的或被superuser调用过的表。这种形式的CLUSTER不能在事务或函数内调用。
当一张表正在被执行聚簇时,会在其上加ACCESS EXCLUSIVE锁,这时其它操作包括读和写都不能在聚簇完成前执行。
适用情况和注意事项:
当你随意的取一张表中的单独的一些行时,数据在表中的真实顺序是无关紧要的。但是当你经常取某些数据时,用聚簇索引将这些数据聚集在一起时会非常有效。
考虑你要取某一范围内的数据,或者一个索引项有很多行满足条件情况下,由于CLUSTER按照指定索引的顺序将数据从物理地址上按序排列,所以一旦索引寻找到某条满足的记录,其它可能满足的数据极有可能和这条记录在同一扇页中,从而减少了取数据时的磁盘寻道和等待的时间。这种情况下CLUSTER很有效果。
在聚簇执行期间,系统将会建立一个临时的表,这张表将数据按索引顺序存储。同时这张表上的索引本身也会有一个临时的拷贝。因此,你至少需要有这张表与其上的索引大小总和的空余磁盘空间。
由于CLUSTER记住了聚簇的信息,用户可以在第一次手动聚簇后设定一个类似于VACUUM的时间间隔,系统会周期性的自动重新聚簇。
还有另外的方法来聚簇数据。CLUSTER命令根据指定的索引次序重新排列表。如果表很大时需要从索引堆中不停的取大量数据,这种情况下尽管有缓存的帮助,执行速度还是会很慢。这时可以用下面的方法:
CREATE TABLE newtable AS
SELECT columnlist FROM table ORDER BY columnlist;用排序命令ORDER BY实现要求的次序;通常这样做会比扫描无序的数据聚簇速度快。接着删除旧表,用ALTER TABLE …RENAME那个newtable为旧表的名字,再重新在这张表上建索引。但是这样做并不能保证原来的OID的性质被保留,如数据约束、外键关系、授权等级等等,这些都必须手动重新建立。
下面用个例子具体介绍:
根据索引emp_ind将表employee聚簇:
CLUSTER emp_ind ON emp;
用同样的索引聚簇表employee
CLUSTER emp;
(重新)聚簇这个数据库中先前所有聚簇过的表:
CLUSTER;
SQL标准里并没有要求CLUSTER,所以还要看各个数据库的各种不同的支持情况
另外可以参照clusterdb命令