CLUSTER — 根據索引對錶進行聚集
CLUSTER [ (option
[, ...] ) ] [table_name
[ USINGindex_name
] ] whereoption
can be one of: VERBOSE [boolean
]
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-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
[ USINGindex_name
] ]
以下語法在 PostgreSQL 8.3 之前使用,並且仍然受支援
CLUSTERindex_name
ONtable_name
如果您在文件中發現任何不正確、與您實際使用經驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。