CLUSTER

根据索引对磁盘上的堆存储表进行物理重新排序。不是在Greenplum数据库中推荐的操作。

概要

  1. CLUSTER indexname ON tablename
  2. CLUSTER tablename
  3. CLUSTER

描述

CLUSTER 根据索引订购堆存储表。 CLUSTER 在追加优化的存储表中不支持。 聚类索引意味着记录根据索引信息在磁盘上进行物理排序。如果用户需要的记录随机分布在磁盘上,那么数据库必须在磁盘上查找以获取请求的记录。如果这些记录更紧密地存储在一起,那么从磁盘读取更顺序。聚集索引的一个很好的例子是在日期列中, 其中数据按日期顺序排列。针对特定日期范围的查询将导致从磁盘进行有序的提取,从而利用更快的顺序访问。

聚类是一次性操作:当表随后更新时,更改不会聚类。也就是说,没有尝试根据其索引顺序存储新的或更新的行。如果有人愿意,可以通过再次发出命令来定期重新排队。

当一个表被更新时,Greenplum会记住它是按照哪个索引聚簇的。形式 CLUSTER tablename会使用前面所用的同一个索引对表重新聚簇。不带任何参数的 CLUSTER 会重新聚集调用用户拥有的当前数据库中所有以前的群集表,或者超级用户调用的所有表。 这种形式的 CLUSTER 不能在一个事务块内执行。

当一个表被聚簇时,会在其上要求一个 ACCESS EXCLUSIVE 锁。这会阻止任何其他数据库操作(包括读和写)在CLUSTER 结束前在该表上操作。

参数

indexname

一个索引的名称。

tablename

一个表的名称(可能是方案限定的)。

注解

在随机访问一个表中的行时,表中数据的实际顺序是无关紧要的。 不过,如果用户想要更多地访问其中一些数据,并且有一个索引把它 们分组在一起,使用 CLUSTER就会带 来好处。 如果用户从一个表中要求一个范围的被索引值或者多行都匹 配的一个单一值,CLUSTER 就会有所 帮助,因为一旦该索引标识出了第一个匹配行所在的表页,所有其 他匹配行很可能就在同一个表页中,并且因此节省了磁盘访问并且 提高了查询速度。

在集群操作期间,创建表的临时副本,其中包含索引顺序中的表数据。也创建表上每个索引的临时副本。因此,用户需要至少等于表大小和索引大小之和的磁盘上的可用空间。

因为规划器会记录有关表顺序的统计信息,建议在新近被聚簇的表上 运行 ANALYZE 。 否则,规划器可能会产生很差 的查询计划。

还有另一种聚类数据的方式。CLUSTER comm命令通过使用用户指定的索引扫描原始表来重新排序。这在大型表格上可能很慢,因为以索引顺序从表中提取行,如果表无序,则条目在随机页面上,因此每个移动的行都检索到一个磁盘页面。(Greenplum数据库有一个缓存,但大部分的大表不适合缓存。)集群表的另一种方法是使用如下语句:

  1. CREATE TABLE newtable AS SELECT * FROM table ORDER BY column;

这使用Greenplum数据库排序代码来产生所需的顺序,通常要比无序数据的索引扫描快得多。然后用户删除旧表, 使用ALTER TABLE … RENAME 将 newtable重命名为旧名称,并重新创建表的索引。这种方法的最大缺点是它不保留表的OID,约束,授予权限和其他辅助属性 - 所有这些项必须手动重新创建。另一个缺点是这样需要与表本身大小相同的排序临时文件,因此峰值磁盘使用量大约是表大小的三倍,而不是表大小的两倍。

注意: CLUSTER 不支持追加优化的表。

示例

基于索引employees 的聚集表 emp_ind:

  1. CLUSTER emp_ind ON emp;

通过重新创建并以正确的索引顺序加载它来集群大型表: order:

  1. CREATE TABLE newtable AS SELECT * FROM table ORDER BY column;
  2. DROP table;
  3. ALTER TABLE newtable RENAME TO table;
  4. CREATE INDEX column_ix ON table (column);
  5. VACUUM ANALYZE table;

兼容性

在SQL标准中没有 CLUSTER 语句。

另见

CREATE TABLE AS, CREATE INDEX

上级主题: SQL命令参考