CLUSTER
根据索引对磁盘上的堆存储表进行物理重新排序。 在Greenplum数据库中不建议执行此操作。
概要
CLUSTER indexname ON tablename
CLUSTER [VERBOSE] tablename
CLUSTER [VERBOSE]
描述
CLUSTER根据索引对堆存储表进行排序。 追加优化存储表不支持CLUSTER。 对索引进行聚簇意味着根据索引信息在磁盘上对记录进行物理排序。 如果您需要的记录随机分布在磁盘上,则数据库必须跨磁盘搜索以获取请求的记录。 如果将这些记录更紧密地存储在一起,则从磁盘进行的获取将更加有序。 聚集索引的一个很好的例子是在date列上,该列按日期顺序对数据进行排序。 对特定日期范围的查询将导致从磁盘中有序地进行访问,从而利用了更快的顺序访问。
聚簇是一项一次性操作:表在随后进行更新时,更改不会被聚簇。 也就是说,没有尝试根据新的或更新的行的索引顺序来存储它们。 如果您愿意,可以通过再次发出命令来定期重新聚簇。 将表的FILLFACTOR存储参数设置为小于100%可以有助于在更新期间保留聚簇顺序,因为如果那里有足够的空间,则更新的行将保留在同一页上。
当使用此命令将表聚簇时,Greenplum数据库会记住该表在哪个索引上聚簇。 形式CLUSTER tablename将表重新聚集在与聚簇相同的索引上。 您可以使用ALTER TABLE的CLUSTER或SET WITHOUT CLUSTER形式来设置索引以用于将来的聚簇操作,或清除任何先前的设置。 不带任何参数的CLUSTER会重新聚簇调用用户所拥有的当前数据库中所有先前聚簇的表,或者重新聚簇所有表(如果由超级用户调用)。 这种形式的CLUSTER不能在事务块内执行。
对表进行聚簇时,将在其上获取ACCESS EXCLUSIVE锁。 这样可以防止在表CLUSTER完成之前对表执行任何其他数据库操作(读取和写入)。
参数
indexname
索引名称。
VERBOSE
当每个表聚簇时,打印进度报告。
tablename
表的名称(可以由模式指定)。
注解
如果您要随机访问表中的单个行,则表中数据的实际顺序并不重要。 但是,如果您倾向于访问比其他数据更多的数据,并且有一个将它们分组在一起的索引,则可以从使用CLUSTER中受益。 如果要从表中请求某个范围的索引值,或者是具有多个匹配行的单个索引值, 则CLUSTER会有所帮助,因为一旦索引为匹配的第一行标识了表页面, 则所有其他匹配的行都可能已经在同一表页面上,因此您可以节省磁盘访问并加快查询速度。
CLUSTER可以使用对指定索引的索引扫描或顺序扫描后再排序来对表进行重新排序(如果索引是b树)。 它将尝试根据优化器成本参数和可用的统计信息来选择更快的方法。
使用索引扫描时,将创建表的临时副本,该副本包含按索引顺序排列的表数据。 还将创建表上每个索引的临时副本。 因此,磁盘上需要的可用空间至少等于表大小和索引大小的总和。
当使用顺序扫描和排序时,还会创建一个临时排序文件,因此临时空间的峰值需求是表大小加索引大小的两倍。 此方法通常比索引扫描方法快,但是如果磁盘空间需求无法忍受,则可以通过将enable_sort配置参数临时设置为off来禁用此选择。
建议在聚簇之前将maintenance_work_mem配置参数设置为一个相当大的值(但不要大于您可以用于CLUSTER操作的RAM数量)。
因为查询优化器会记录有关表顺序的统计信息,所以建议在新的聚簇表上运行ANALYZE。 否则,优化器可能会选择错误的查询计划。
由于CLUSTER会记住对哪些索引进行了聚簇,因此您可以在第一次手动对要聚簇的表进行聚簇, 然后设置一个定期维护脚本,该脚本无需任何参数即可执行CLUSTER,以便定期重新聚簇所需的表。
Note: 追加优化表不支持CLUSTER。
示例
根据索引emp_ind对表employees进行聚簇:
CLUSTER emp_ind ON emp;
通过重新创建大型表并将其以正确的索引顺序加载来对大型表进行聚簇:
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 INDEX
Parent topic: SQL Command Reference