↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / SQL 命令 / 维护

SQL COMMAND · 维护

CLUSTER

按照一个索引对表进行聚簇

CLUSTER维护引入 10(基线)现存至 20 devel2 次语法变更

动词
CLUSTER
对象
—
分组
维护
引入版本
10(基线)
状态
现存
语法变更次数
2
手册小节数
6

本站手册 · 18官方文档 ↗

版本轨迹

相对 PostgreSQL 17 语法未变,正文有更新。

语法铁道图 PostgreSQL 18

沿轨道从左向右阅读,分岔表示选择,绕行表示可选,回环表示重复。方框为参数,点击带下划线的参数可展开子规则。

CLUSTER ( option , ) table_name USING index_name
option
VERBOSE boolean

锁模式 PostgreSQL 18

具体锁模式取决于操作变体、目标对象和执行阶段;同一命令可同时取得表锁与行锁。查看完整冲突矩阵

ACCESS EXCLUSIVE · 表级锁

CLUSTER:重写目标表期间阻止并发读写。

语法概要

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

其中 option 可以是以下之一:

    VERBOSE [ boolean ]

PostgreSQL 18 手册 · 查看完整参考页

描述

CLUSTER 指示 PostgreSQL 按照 index_name 指定的索引,对 table_name 指定的表进行聚簇。该索引必须已经定义在 table_name 上。

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

当一个表被聚簇时,PostgreSQL 会记住该表是按哪个索引聚簇的。形式 CLUSTER table_name 会使用与之前相同的索引对表重新聚簇。你也可以使用 ALTER TABLE 的 CLUSTER 或 SET WITHOUT CLUSTER 形式,设置未来聚簇操作要使用的索引,或者清除任何先前的设置。

不带 table_name 的 CLUSTER 会对当前数据库中所有此前已聚簇且调用用户具有相应权限的表重新执行聚簇。这种形式的 CLUSTER 不能在事务块内执行。

当对一个表执行聚簇时,会在该表上获取 ACCESS EXCLUSIVE 锁。这会阻止任何其他数据库操作(包括读和写)在 CLUSTER 完成前访问该表。

参数

table_name

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

index_name

索引的名称。

VERBOSE

在每个表被聚簇时,以 INFO 级别打印进度报告。

boolean

指定所选选项是否开启。可以写TRUE、ON或1来启用选项,写FALSE、OFF或0来禁用它。也可以省略boolean值,此时假定为TRUE。

注解

要对表执行聚簇,必须在该表上具有 MAINTAIN 权限。

当你在表中随机访问单行时,数据在表中的实际顺序并不重要。但是,如果访问某些数据比其他数据更频繁,并且存在将这些数据放在一起的索引,使用CLUSTER就会有益。如果要从表中获取一段索引值范围,或者获取有多行匹配的单个索引值,CLUSTER会有帮助,因为一旦索引确定第一个匹配行所在的表页,其他匹配行很可能已在同一个表页中,从而减少磁盘访问并加快查询。

CLUSTER 可以通过在指定索引上进行索引扫描,或者(如果该索引是 B-树)先执行顺序扫描再排序,来对表重新排序。它会根据规划器代价参数和可用的统计信息,尝试选择速度更快的方法。

在 CLUSTER 执行期间,search_path会被临时设置为 pg_catalog, pg_temp。

使用索引扫描时,会创建一个表的临时副本,其中表数据按索引顺序排列。还会为表上的每个索引创建临时副本。因此,所需的磁盘空闲空间至少应等于表大小与索引大小之和。

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

建议在聚簇之前将maintenance_work_mem设置为一个合理的大值(但不超过可专门用于CLUSTER操作的内存量)。

因为规划器会记录有关表中数据顺序的统计信息,建议在新近聚簇过的表上运行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

另见

语法演化

相邻大版本之间的差异,新的在前。版本号链接到对应快照。

  1. PostgreSQL 19← 18正文更新

    正文更新
  2. PostgreSQL 18← 17正文更新

    正文更新
  3. PostgreSQL 17← 16语法变化

    + CLUSTER [ ( option [, ...] ) ] [ table_name [ USING index_name ] ]− CLUSTER [VERBOSE] table_name [ USING index_name ]− CLUSTER ( option [, ...] ) table_name [ USING index_name ]− CLUSTER [VERBOSE]正文更新
  4. PostgreSQL 16← 15正文更新

    正文更新
  5. PostgreSQL 15← 14正文更新

    正文更新
  6. PostgreSQL 14← 13语法变化

    + CLUSTER ( option [, ...] ) table_name [ USING index_name ]+ CLUSTER [VERBOSE]+ VERBOSE [ boolean ]正文更新

同组命令

命令动词对象版本变动最近变更
MAINTENANCE维护4 条↑
ANALYZEANALYZE— 185 次
收集数据库的统计信息现存
CHECKPOINTCHECKPOINT— 191 次
强制执行一次预写式日志检查点现存
CLUSTERCLUSTER— 172 次
按照一个索引对表进行聚簇现存
VACUUMVACUUM— 198 次
垃圾收集并按需分析数据库现存