PostgreSQL 9.0.0文書
前のページ | 巻戻し |  | 早送り | 次のページ

# CLUSTER

## 名前

CLUSTER -- インデックスに従ってテーブルをクラスタ化する

## 概要

    CLUSTER [VERBOSE] table_name [ USING index_name ]
    CLUSTER [VERBOSE]

## 説明

`CLUSTER`は、`index_name`で指定されたインデックスに基づき、`table_name`で指定されたテーブルをクラスタ化するように、PostgreSQLに指示します。 このインデックスは前もって`table_name`で定義されていなければなりません。

テーブルがクラスタ化されると、それぞれのテーブルはインデックス情報に基づいて物理的に並べ直されます。 クラスタ化は、1回限りの操作です。 クラスタ化後にテーブルが更新されても、その変更はクラスタ化されません。 つまり、新規に追加された行や更新された行は、インデックス順には保管されません。 （インデックス順に保管したい場合は、コマンドを再度入力し、定期的に再クラスタ化を行います。 また、更新される行は十分な領域が利用可能ならば同一ページ内に保持されますので、テーブルの`FILLFACTOR`格納パラメータを100%より小さく設定することで、更新処理中のクラスタ順序付けを保護するという点で役に立ちます。）

テーブルがクラスタ化されると、PostgreSQLはクラスタ化に使用されたインデックスを記録します。 `CLUSTER `table_name``という構文によって、以前と同じインデックスを使用してテーブルを再クラスタ化します。 またALTER TABLEの`CLUSTER`もしくは`SET WITHOUT CLUSTER`構文を使用して、将来のクラスタ化操作で使用するインデックスを設定したり、任意の過去の設定を取り消すことができます。

パラメータを指定しないで`CLUSTER`を実行した場合、呼び出したユーザが所有する現在のデータベース内の全てのテーブルを（スーパーユーザの場合は、全てのテーブルを）クラスタ化します。 このパラメータを指定しない`CLUSTER`を、トランザクションブロック内で実行することはできません。

クラスタ化を行っているテーブルは、`ACCESS EXCLUSIVE`ロックを獲得しています。 これにより、`CLUSTER`が終わるまで、そのテーブルに対するデータベース操作（読み書き両方）を防ぐことができます。

## パラメータ

`table_name`

  テーブルの名前です（スキーマ修飾名も可）。

`index_name`

  インデックスの名前です。

`VERBOSE`

  各テーブルのクラスタ化を行う時に進行状況報告を出力します。

## 注釈

テーブル内の1つの行にランダムにアクセスする場合、テーブル内のデータの順序は重要でありません。 しかし、テーブル内の特定のデータにアクセスが集中している場合、それらのデータをグループ化しているインデックスが存在する時は、`CLUSTER`による利益を享受できます。 テーブルからインデックスの値の範囲や、一致する複数の行を保有する1つのインデックスの値などが知りたい場合、`CLUSTER`が役に立ちます。 一度インデックスが一致する行に対するテーブルページを認識すると、一致する他の全ての行も同じテーブルページに存在する可能性が高いので、ディスクアクセスを減らして問い合わせ処理の速度を向上することができるからです。

クラスタ処理の間、インデックス順にテーブルデータを並べた、テーブルの一時コピーが作成されます。 同様に、テーブルの各インデックスの一時コピーも作成されます。 したがって、ディスクには、少なくともテーブルとインデックスの合計サイズと同じ容量の空き領域が必要です。

`CLUSTER`はクラスタ化に関する情報を記録しているので、一度手作業でテーブルをクラスタ化すれば、周期的に再クラスタ化を実行するよう、`VACUUM`同様にスケジュールを組むことができます。

プランナはテーブルの順序付けに関する統計情報を記録しているため、新しくクラスタ化されたテーブルでは、ANALYZEを実行することが推奨されます。 そうしないと、プランナが問い合わせ計画を適切に選択できない可能性があります。

データをクラスタ化する方法はもう1つあります。 `CLUSTER`コマンドは、指定したインデックスを使用してテーブルをスキャンすることで元のテーブルを並び替えます。 この方法では、行はインデックスの順序にテーブルから取り出されますが、テーブルが順番に並んでいない場合、それぞれの項目がばらばらの順序でページ上に存在するため、移動する行ごとに1つのディスクページが取得されることになります。 したがって、大規模なテーブルでは低速になることがあります （PostgreSQLにはキャッシュがありますが、大規模なテーブルの大多数はキャッシュに収めきれません）。 次に、テーブルをクラスタ化するもう1つの方法を示します。

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

このSQL文では、PostgreSQLのソート用のコードを使用し、必要な並び替えを作成しています。 この方法は、通常、順序付けられていないデータに対するインデックススキャンよりも処理時間がずっと短くなります。 その後、古いテーブルを削除し、`ALTER TABLE...RENAME`で`newtable`を以前の名前に書き換えてから、テーブルのインデックスを再生成してください。 しかし、この方法では、テーブルのOID、制約、外部キー関係、権限、およびその他の付属情報が保持されないという大きな欠点があります。 これらの付属情報は、手動で再作成する必要があります。 他にもこの方法には、対象のテーブル自体と同サイズの、一時的なソート用のファイルが必要であるという欠点もあります。 このため、最大のディスク使用量はテーブルサイズの倍ではなく約3倍になります。

## 例

`employees_ind`インデックスに基づいて、`emp`テーブルをクラスタ化します。

    CLUSTER employees USING employees_ind;

以前に使用したインデックスを使用して、`employees`テーブルをクラスタ化します。

    CLUSTER employees;

データベース内の、以前にクラスタ化されたテーブルを全てクラスタ化します。

    CLUSTER;

## 互換性

標準SQLには`CLUSTER`文はありません。

    CLUSTER index_name ON table_name

という構文も、8.3より前のバージョンのPostgreSQLとの互換性のためサポートされます。

## 関連項目

clusterdb

前のページ | ホーム | 次のページ
CLOSE | 上に戻る | COMMENT