CLUSTER indexname ON table
当对一个表建簇后,该表的物理存储将基于索引信息进行.建簇是静态的,也就是说,当表被更新后,改变的内容不会建簇.不会试图对更新过的记录重新建簇.如果需要,可以通过手工执行该命令的方法重建簇.
如果你只是随机的访问表中的行,那么在堆表中的数据的实际存储顺序是无关紧要的.但是,如果你对某些数据的访问多于其他数据,而且有一个索引将这些数据分组,那你就将从 CLUSTER 中获益.
另一个 CLUSTER 很有帮助的例子是当你用索引从一个表中取出几个记录时.如果你从一个表中请求一定索引范围的值,或者是一个索引过的值对应多行,CLUSTER 也会有助于应用,因为如果索引标识出第一匹配行所在的堆存储页,所有其他行也可能已经在同一堆存储页里了,这样便节省了磁盘访问的时间,加速了查询.
有两种建簇的数据.第一种是用 CLUSTER 命令,此命令将原表按你声明的索引重新排列.这个动作在操作大表时可能会很慢,因为每一行都从堆存储页里按索引顺序取出,如果存储页表没有排序,整个表是随机存放在各个页面的,因而每行都要进行依次磁盘页面操作.Postgres 有一个缓冲,但一个大表的主体是不可能都放到缓冲去的.
另一个对数据建簇的方法是使用
SELECT columnlist INTO TABLE newtable FROM table ORDER BY columnlist这个用法使用 Postgres 排序的代码 ORDER BY 来匹配索引,在对未排序的数据操作时速度快得多.然后你可以删除旧表,用 ALTER TABLE/RENAME 将 temp 改成旧表名,并且重建所有索引.唯一的问题是 OID 将不保留.这时再做 CLUSTER 将快得多,因为大多数堆栈数据已经排过序了而且使用现有的索引.
CLUSTER emp_ind ON emp;