CLUSTER

Name

CLUSTER -- 根據一個索引對某個資料表集簇

Synopsis

CLUSTER indexname ON tablename
CLUSTER tablename
CLUSTER
  

描述

CLUSTER 指示PostgreSQL 基於索引 indexname 的度量對資料表 table 進行儲存建簇。索引必須已經在資料表 tablename. 上定義。

當對一個資料表建簇後,該資料表的實際儲存將基於索引訊息進行。 建簇是一次性操作:也就是說,當資料表隨後被更新後,改變的內容不會建簇。 也就是說,系統不會試圖按照索引順序對更新過的記錄重新建簇。 如果需要,可以透過週期性地手工執行該命令的方法重建簇。

在對一個資料表建簇之後,PostgreSQL 會記憶在哪個索引上建立的簇。 CLUSTER tablename 的形式就在資料表以前建簇的同一個索引上建簇。

沒有任何參數的 CLUSTER 將導致目前資料庫裡所有調用它的用戶所有的資料表都被建簇。 (絕不會對不包括進來的資料表建簇。)這種形式的 CLUSTER 不能在一個交易或者函數里面調用。

在對一個資料表進行建簇的時候,則在其上請求一個 ACCESS EXCLUSIVE 鎖。 這樣就避免了在 CLUSTER 完成之前執行任何其他的資料庫操作(包括讀寫)。 參閱 Section 12.3 獲取有關資料庫鎖定的更多訊息。

參數

indexname

一個索引名稱。

table

準備建簇的資料表的名稱(可能有模式修飾)。

注意

如果您只是隨機的訪問資料表中的行, 那麼在堆資料表中的資料的實際儲存順序是無關緊要的。 但是,如果您對某些資料的訪問多於其他資料, 而且有一個索引將這些資料分組,那您就將從使用 CLUSTER 中獲益。 如果您從一個資料表中請求一定索引範圍的值, 或者是一個索引過的值對應多行, CLUSTER 也會有助於應用, 因為如果索引標識出第一匹配行所在的堆儲存頁,所有其他行也可能已經在同一堆儲存頁裡了, 這樣便節省了磁盤訪問的時間,加速了查詢。

在這個建簇的操作過程中,系統先建立一個按照索引順序建立的資料表的臨時拷貝。 同時也建立資料表上的每個索引的臨時拷貝。因此,您需要磁盤上有足夠的剩餘空間, 至少是資料表大小和索引大小的和。

因為 CLUSTER 記憶建簇訊息,我們可以在第一次的時候手工對資料表進行建簇, 然後設置一個類似 VACUUM 的時間, 這樣我們就可以週期地自動對資料表進行建簇了。

因為規劃器記錄著有關資料表的排序的統計,所以我們建議在新近建簇的資料表上執行 ANALYZE。 否則,規劃器可能會選擇很差勁的查詢規劃。

還有一種建簇的方法。 CLUSTER 命令將原資料表按您聲明的索引重新排列。 這個動作在操作大資料表時可能會很慢, 因為每一行都從堆儲存頁裡按索引順序取出,如果儲存頁資料表沒有排序, 整個資料表是隨機存放在各個頁面的,因而移動的每一行都要進行一次磁盤頁面操作。 PostgreSQL 有一個緩衝, 但一個大資料表的主體是不可能都放到緩衝去的。 另外一種對資料表建簇的方法是

CREATE TABLE newtable AS
    SELECT columnlist FROM table ORDER BY columnlist;

這個用法使用PostgreSQL 排序的代碼 ORDER BY 來建立一個需要的順序,在對未排序的資料操作時通常速度比索引掃瞄快得多。 然後您可以刪除舊資料表,用 ALTER TABLE ... RENAMEnewtable 改成舊資料表名, 並且重建該資料表所有索引。但是,這個方法不保留 OID,約束,外鍵關係, 賦予的權限,以及資料表的其它附屬的屬性 — 所有這些屬性都必須手工重建。

例子

以僱員的 emp_ind 屬性對employees資料表建簇。

CLUSTER emp_ind ON emp;
  

使用以前用過的同一個索引對employees資料表進行建簇:

CLUSTER emp;

對以前建過簇的所有資料表進行建簇:

CLUSTER;

相容性

在 SQL92 規範裡沒有 CLUSTER 語句。

又見

clusterdb