2025年9月25日: PostgreSQL 18 发布!
支持的版本:当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

CLUSTER

CLUSTER — 根据索引对表进行聚集

概要

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

where option can be one of:

    VERBOSE [ boolean ]

描述

CLUSTER 指示 PostgreSQL 根据 index_name 指定的索引对 table_name 指定的表进行聚集。该索引必须已在 table_name 上定义。

当一个表被聚集时,它会根据索引信息被物理重排。聚集是一次性操作:当表之后被更新时,这些更改不会被聚集。也就是说,不会尝试按照索引顺序存储新行或更新后的行。(如果需要,可以再次发出该命令来定期重新聚集。此外,将表的 fillfactor 存储参数设置为小于 100% 可以帮助在更新期间保持聚集顺序,因为如果更新后的行有足够的空间,它们会保留在同一页面上。)

当一个表被聚集时,PostgreSQL 会记住它是由哪个索引聚集的。CLUSTER table_name 的形式会使用与之前相同的索引重新聚集该表。您还可以使用 ALTER TABLECLUSTERSET WITHOUT CLUSTER 形式来设置将来用于聚集操作的索引,或清除任何之前的设置。

不带 table_nameCLUSTER 会重新聚集当前数据库中所有先前已聚集且调用用户拥有权限的表。此形式的 CLUSTER 不能在事务块内执行。

当一个表正在被聚集时,会对其获取一个 ACCESS EXCLUSIVE 锁。这会阻止任何其他数据库操作(读写)在该表上进行,直到 CLUSTER 完成为止。

参数

table_name

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

index_name

索引的名称。

VERBOSE

在对每个表进行聚集时,在 INFO 级别打印进度报告。

boolean

指定是否应打开或关闭选定的选项。您可以编写 TRUEON1 来启用选项,编写 FALSEOFF0 来禁用选项。boolean 值也可以省略,在这种情况下假定为 TRUE

注释

要聚集一个表,必须拥有该表的 MAINTAIN 权限。

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

CLUSTER 可以使用指定索引的索引扫描,或者(如果索引是 b-tree)顺序扫描后排序来重新排序表。它会尝试根据规划器成本参数和可用统计信息来选择更快的执行方法。

CLUSTER 运行时,search_path 会被临时更改为 pg_catalog, pg_temp

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

当使用顺序扫描和排序时,还会创建一个临时的排序文件,因此峰值临时空间需求可能高达表大小的两倍,再加上索引大小。此方法通常比索引扫描方法更快,但如果磁盘空间需求无法忍受,可以通过临时将 enable_sort 设置为 off 来禁用此选项。

建议在聚集之前将 maintenance_work_mem 设置为一个相当大的值(但不要超过您可以为此 CLUSTER 操作分配的 RAM 量)。

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

由于 CLUSTER 会记住哪些索引被聚集了,您可以先手动聚集您想要聚集的表,然后设置一个定期的维护脚本来执行不带任何参数的 CLUSTER,以便期望的表能够定期被重新聚集。

每个运行 CLUSTER 的后端都将在 pg_stat_progress_cluster 视图中报告其进度。有关详细信息,请参见 Section 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, Section 27.4.2

提交更正

如果您在文档中发现任何不正确、与您实际使用经验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。