Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

CLUSTER

CLUSTER — 将表根据索引聚簇

语法

CLUSTER [ ( option [, ...] ) ] [ table_name [ USING index_name ] ]

where option can be one of:

    VERBOSE [ boolean ]

描述

CLUSTER 指示 PostgreSQL 将由 table_name 指定的表基于由 index_name指定的索引进行聚簇。该索引必须已经在 table_name 上进行定义。

簇集表后,会根据索引信息按物理方式对其重新排序。簇集是一次性操作:表随后更新时,将不会进行簇集。也就是说,不会尝试按照索引顺序存储新增或更新的行。(如果愿意,可以随时通过再次发出该命令进行重新簇集。此外,将表的fillfactor存储参数设置为小于 100% 有助于在更新期间保留簇集顺序,因为如果有足够可用空间,将会在同一页上保留更新的行。)

簇集表后,PostgreSQL 将记住按哪个索引对其进行簇集。格式 CLUSTER table_name 会使用之前相同的索引对该表进行重新簇集。还可以使用 ALTER TABLECLUSTERSET WITHOUT CLUSTER格式来设置用于未来簇集操作的索引,或清除所有先前的设置。

CLUSTER 如果不带table_name,将对当前数据库中所有先前已簇集的表进行重新簇集,条件是调用用户拥有对应权限。这种格式的CLUSTER不能在事务块中执行。

簇集表时,将对其获取ACCESS EXCLUSIVE锁。在CLUSTER完成之前,这将阻止其他任何数据库操作(包括读写)在该表上进行操作。

参数

table_name

表的名称(可能带有模式限定)。

index_name

索引的名称。

VERBOSE

在每个表簇集时打印进度报告。

boolean

指定应启用还是禁用已选选项。可以编写TRUEON1来启用该选项,以及FALSEOFF0来禁用该选项。boolean值也可以省略,在这种情况下,将假设为TRUE

注释

要簇集表,必须具有对该表的MAINTAIN 权限。

在您随机访问表中的单行的情况下,表中数据的实际顺序并不重要。但是,如果您倾向于访问某些数据超过其他数据,并且有一个将它们分组在一起的索引,那么您将受益于使用 CLUSTER。如果您从表中请求范围索引值,或者匹配多行的单一的索引值,CLUSTER 将有所帮助,因为一旦索引识别出匹配第一行的表页,所有其他匹配行可能已经在同一个表页上,从而节省磁盘访问并加快查询。

CLUSTER 可以使用指定索引上的索引扫描,或(如果索引是 b 树)一个顺序扫描,然后排序,重新对表进行排序。它将尝试选择基于规划器成本参数和可用的统计信息,将更快的那个方法。

CLUSTER 运行时,search_path 将暂时更改为 pg_catalog, pg_temp

当使用索引扫描时,将创建包含以索引顺序排列的表数据的表的临时副本。也会创建表上每个索引的临时副本。因此,您需要磁盘上的空余空间至少等于表大小和索引大小的总和。

当使用顺序扫描和排序时,也会创建一个临时排序文件,以便临时的峰值空间需求高达表大小的两倍,加上索引大小。此方法通常比索引扫描方法快,但是如果磁盘空间需求不可容忍,您可以通过将 enable_sort 暂时设置为 off 来禁用此选择。

在做 cluster 之前,建议将 maintenance_work_mem 设置为相当大的值(但不要超过可以专门用于 CLUSTER 操作的 RAM 量)。

因为规划器记录关于表顺序的统计信息,所以建议在新的集群表上运行 ANALYZE。否则,规划器可能会对查询计划做出糟糕的选择。

由于 CLUSTER 可记住哪些索引是已聚集的,因此,可以第一次手动聚集希望聚集的表,然后设置一个定期执行 CLUSTER(无任何参数)的维护脚本,以便定期对目标表重新聚集。

每个运行 CLUSTER 的后端将在 pg_stat_progress_cluster 视图中报告其进度。有关详细信息,请参阅 第27.4.2节

聚集分区表会使用指定分区索引的分区来聚集其每个分区。在聚集分区表时,不能省略索引。对于分区表,不能在事务块内执行 CLUSTER

示例

基于其索引 employees_ind 聚集表 employees

CLUSTER employees USING employees_ind;

使用之前已使用的相同索引,聚集 employees

CLUSTER employees;

聚集数据库中先前已聚集的所有表

CLUSTER;

兼容性

SQL 标准中没有 CLUSTER 语句。

以下语法在 PostgreSQL 17 之前使用,并且仍然支持

CLUSTER [ VERBOSE ] [ table_name [ USING index_name ] ]

以下语法在 PostgreSQL 8.3 之前使用,并且仍然支持

CLUSTER index_name ON table_name

另请参阅

clusterdb第27.4.2节