选择 打开 改范围 完整检索页

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

文档 / SQL 命令 / 维护

SQL COMMAND · 维护

CLUSTER

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

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

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

本站手册 · 18官方文档 ↗

版本轨迹

相对 PostgreSQL 17 无变化。

语法铁道图 PostgreSQL 18

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

CLUSTER ( option , ) table_name USING index_name
option
VERBOSE boolean

语法概要

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 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-树)先执行顺序扫描再排序,来对表重新排序。它会 根据规划器代价参数和可用的统计信息,尝试选择速度更快的方法。

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.4

对分区表进行聚簇时,会使用指定分区索引在各分区上的对应分区索引来 聚簇每个分区。对分区表执行聚簇时,索引不可省略。 对分区表执行 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 14← 13语法变化

    + CLUSTER [ ( option [, ...] ) ] [ table_name [ USING index_name ] ]+ + 其中 option 可以是以下之一:+ + VERBOSE [ boolean ]− CLUSTER [VERBOSE] table_name [ USING index_name ]− CLUSTER [VERBOSE]正文更新

同组命令

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