CLUSTER
根据索引对磁盘上的堆存储表进行物理重新排序。不是在Greenplum数据库中推荐的操作。
概要
CLUSTER indexname ON tablename
CLUSTER tablename
CLUSTER
描述
CLUSTER
根据索引订购堆存储表。
CLUSTER
在追加优化的存储表中不支持。
聚类索引意味着记录根据索引信息在磁盘上进行物理排序。如果用户需要的记录随机分布在磁盘上,那么数据库必须在磁盘上查找以获取请求的记录。如果这些记录更紧密地存储在一起,那么从磁盘读取更顺序。聚集索引的一个很好的例子是在日期列中,
其中数据按日期顺序排列。针对特定日期范围的查询将导致从磁盘进行有序的提取,从而利用更快的顺序访问。
聚类是一次性操作:当表随后更新时,更改不会聚类。也就是说,没有尝试根据其索引顺序存储新的或更新的行。如果有人愿意,可以通过再次发出命令来定期重新排队。
当一个表被更新时,Greenplum会记住它是按照哪个索引聚簇的。形式 CLUSTER
tablename会使用前面所用的同一个索引对表重新聚簇。不带任何参数的
CLUSTER
会重新聚集调用用户拥有的当前数据库中所有以前的群集表,或者超级用户调用的所有表。
这种形式的 CLUSTER
不能在一个事务块内执行。
当一个表被聚簇时,会在其上要求一个 ACCESS EXCLUSIVE
锁。这会阻止任何其他数据库操作(包括读和写)在CLUSTER
结束前在该表上操作。
参数
indexname 一个索引的名称。 tablename 一个表的名称(可能是方案限定的)。
注解
在随机访问一个表中的行时,表中数据的实际顺序是无关紧要的。 不过,如果用户想要更多地访问其中一些数据,并且有一个索引把它 们分组在一起,使用 CLUSTER
就会带 来好处。
如果用户从一个表中要求一个范围的被索引值或者多行都匹 配的一个单一值,CLUSTER
就会有所 帮助,因为一旦该索引标识出了第一个匹配行所在的表页,所有其 他匹配行很可能就在同一个表页中,并且因此节省了磁盘访问并且 提高了查询速度。
在集群操作期间,创建表的临时副本,其中包含索引顺序中的表数据。也创建表上每个索引的临时副本。因此,用户需要至少等于表大小和索引大小之和的磁盘上的可用空间。
因为规划器会记录有关表顺序的统计信息,建议在新近被聚簇的表上 运行
ANALYZE
。 否则,规划器可能会产生很差 的查询计划。
还有另一种聚类数据的方式。CLUSTER
comm命令通过使用用户指定的索引扫描原始表来重新排序。这在大型表格上可能很慢,因为以索引顺序从表中提取行,如果表无序,则条目在随机页面上,因此每个移动的行都检索到一个磁盘页面。(Greenplum数据库有一个缓存,但大部分的大表不适合缓存。)集群表的另一种方法是使用如下语句:
CREATE TABLE newtable AS SELECT * FROM table ORDER BY column;
这使用Greenplum数据库排序代码来产生所需的顺序,通常要比无序数据的索引扫描快得多。然后用户删除旧表, 使用ALTER TABLE ... RENAME
将 newtable重命名为旧名称,并重新创建表的索引。这种方法的最大缺点是它不保留表的OID,约束,授予权限和其他辅助属性 - 所有这些项必须手动重新创建。另一个缺点是这样需要与表本身大小相同的排序临时文件,因此峰值磁盘使用量大约是表大小的三倍,而不是表大小的两倍。
注意: CLUSTER
不支持追加优化的表。
示例
基于索引employees
的聚集表
emp_ind
:
CLUSTER emp_ind ON emp;
通过重新创建并以正确的索引顺序加载它来集群大型表: order:
CREATE TABLE newtable AS SELECT * FROM table ORDER BY column;
DROP table;
ALTER TABLE newtable RENAME TO table;
CREATE INDEX column_ix ON table (column);
VACUUM ANALYZE table;
兼容性
在SQL标准中没有 CLUSTER
语句。
另见
[CREATE TABLE AS](CREATE_TABLE_AS.html#topic1)
,
[CREATE INDEX](CREATE_INDEX.html#topic1)
上级主题: SQL命令参考