支持的版本:当前 (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

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

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 视图中报告其进度。有关详细信息,请参阅第 27.4.2 节

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

示例

根据 employees 表的索引 employees_ind 聚集该表

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 节

提交更正

如果您在文档中看到任何不正确、与您使用特定功能的体验不符或需要进一步澄清的内容,请使用此表格报告文档问题。