CLUSTER — インデックスに従ってテーブルをクラスタ化する
CLUSTER [VERBOSE]table_name
[ USINGindex_name
] CLUSTER (option
[, ...] )table_name
[ USINGindex_name
] CLUSTER [VERBOSE] whereoption
can be one of: VERBOSE [boolean
]
CLUSTER
は、index_name
で指定されたインデックスに基づき、table_name
で指定されたテーブルをクラスタ化するように、PostgreSQLに指示します。
このインデックスは前もってtable_name
上に定義されていなければなりません。
テーブルがクラスタ化されると、それぞれのテーブルはインデックス情報に基づいて物理的に並べ直されます。
クラスタ化は、1回限りの操作です。
クラスタ化後にテーブルが更新されても、その変更はクラスタ化されません。
つまり、新規に追加された行や更新された行は、インデックス順には保管されません。
(インデックス順に保管したい場合は、コマンドを再度入力し、定期的に再クラスタ化を行います。
また、更新される行は十分な領域が利用可能ならば同一ページ内に保持されますので、テーブルのfillfactor
格納パラメータを100%より小さく設定することで、更新処理中のクラスタ順序付けを保護するのに役に立ちます。)
テーブルがクラスタ化されると、PostgreSQLはクラスタ化に使用されたインデックスを記録します。
CLUSTER
という構文によって、以前と同じインデックスを使用してテーブルを再クラスタ化します。
またtable_name
ALTER TABLE
のCLUSTER
もしくはSET WITHOUT CLUSTER
構文を使用して、将来のクラスタ化操作で使用するインデックスを設定したり、過去の設定を取り消すことができます。
table_name
を指定しないでCLUSTER
を実行した場合、現在のデータベース内の以前にクラスタ化されたテーブルのうち、呼び出したユーザが所有するすべてのテーブルを(スーパーユーザが実行する場合はすべてのテーブルを)再クラスタ化します。
この形式のCLUSTER
を、トランザクションブロック内では実行できません。
クラスタ化を行っているテーブルでは、ACCESS EXCLUSIVE
ロックが獲得されています。
これにより、CLUSTER
が終わるまで、そのテーブルに対するデータベース操作(読み書き両方)はできません。
table_name
テーブルの名前です(スキーマ修飾名も可)。
index_name
インデックスの名前です。
VERBOSE
各テーブルのクラスタ化を行う時に進行状況報告を出力します。
boolean
選択したオプションをオンにするかオフにするか指定します。
オプションを有効にする場合にはTRUE
、ON
または1
と書くことができ、無効にする場合に>はFALSE
、OFF
または0
と書くことができます。
boolean
の値は省略することもでき、その場合にはTRUE
とみなされます。
テーブル内の個々の行にランダムにアクセスする場合、テーブル内のデータの順序は重要でありません。
しかし、テーブル内の特定のデータにアクセスが集中していて、それらのデータをひとまとめにしているインデックスが存在する時は、CLUSTER
による利益を享受できます。
テーブルからインデックスの値の範囲や、一致する複数の行を保有する1つのインデックスの値を要求する場合、CLUSTER
が役に立ちます。
一度インデックスが一致する最初の行に対するテーブルページを認識すると、一致する他の全ての行も同じテーブルページに存在する可能性が高いので、ディスクアクセスを減らして問い合わせ処理の速度を向上することができるからです。
CLUSTER
は、指定されたインデックスによるインデックススキャン、または(インデックスがB-Treeの場合)シーケンシャルスキャン後のソートのいずれかを用いて、テーブルを再ソートすることができます。
プランナのコストパラメータと利用可能な統計情報に基づき、より高速な方式の選択を試みます。
インデックススキャンが使用される場合、インデックス順にテーブルデータを並べた、テーブルの一時コピーが作成されます。 同様に、テーブルの各インデックスの一時コピーも作成されます。 したがって、ディスクには、少なくともテーブルとインデックスの合計サイズと同じ容量の空き領域が必要です。
シーケンシャルスキャンとソートが使用される場合も一時的なソートファイルが作成されます。
一時的に必要となるサイズの最大値はテーブルサイズの倍のサイズにインデックスサイズを加えた値となります。
この方式はインデックススキャンより高速になることが多いのですが、必要なディスク容量に耐えられない場合は、一時的にenable_sortをoff
にすることで、この方式を無効にすることができます。
クラスタ処理の前にmaintenance_work_memを程良く大きな値に設定することを勧めます。
(しかしCLUSTER
操作専用に割り当てられるRAMの容量を超えないようにしてください。)
プランナはテーブルの順序付けに関する統計情報を記録しているため、新しくクラスタ化されたテーブルでは、ANALYZE
を実行することが推奨されます。
そうしないと、プランナが問い合わせ計画を適切に選択できない可能性があります。
CLUSTER
はどのインデックスでクラスタ化したかを記録していますので、対象のテーブルを定期的に再クラスタ化できるように、最初にクラスタ化したいテーブルを手作業でクラスタ化し、その後にパラメータをまったく持たないCLUSTER
を実行する定期的な保守用スクリプトを設定することができます。
CLUSTER
を実行している各バックエンドはその進捗をpg_stat_progress_cluster
ビューで報告します。
詳細は28.4.2を参照してください。
パーティションテーブルをクラスタ化すると、指定したパーティションインデックスのパーティションを使用して各パーティションがクラスタ化されます。
パーティションテーブルをクラスタ化する場合は、インデックスを省略できません。
パーティションテーブルのCLUSTER
は、トランザクションブロック内では実行できません。
インデックスemployees_ind
に基づいて、テーブルemp
をクラスタ化します。
CLUSTER employees USING employees_ind;
以前に使用したインデックスを使用して、テーブルemployees
をクラスタ化します。
CLUSTER employees;
データベース内の、以前にクラスタ化されたテーブルを全てクラスタ化します。
CLUSTER;
標準SQLにはCLUSTER
文はありません。
CLUSTERindex_name
ONtable_name
という構文も、8.3より前のバージョンのPostgreSQLとの互換性のためサポートされます。