CLUSTER SQL 01/23/93 PostgreSQL PostgreSQL

名前

cluster - Postgres に対して、記憶領域のクラスタリングの指示を与える。

書式

cluster インデックス名 on 属性名
    

説明

このコマンドは Postgres に対して、インデックス名で指定されたインデックス順にだいたい並んでいるクラス名で指定されたクラスをクラスタリングするように指示する。

クラスがまとめられると、それはインデックス情報に基づいて物理的に並べ替えられる。クラスタリングは静的に行われる。つまりクラスが更新されても、変更分はクラスタリングされない。新しいインスタンスや更新されたタプルはクラスタリングに反映されない。もしそう望むのであれば、ユーザがこのコマンドを手作業で再発行することにより、再クラスタリングを行うことができる。

実際にテーブルは、インデックス順で一時テーブルにコピーされ、その後新しい名前にリネームされる。これは、クラスタリングが実行される際に、許可されたすべての権限やその他のインデックスなどが失われてしまうためである。

テーブル内の単一行に対してランダムにアクセスしている場合、ヒープテーブル内における実際のデータの並び方は重要ではない。しかしながら、それ以外のデータにアクセスしたい場合で、それらがお互いにグループ化されている場合は、CLUSTER コマンドが役に立つ。

CLUSTER が役に立つもう 1 つの場面としては、インデックスを使ってテーブルからいくつかの行を取り出す場合があげられる。テーブルからインデックスされた値のうちのある範囲を要求する場合、または、単一のインデックス値がマッチする複数の行がある場合、CLUSTER は役に立つ。これは、インデックスはいったんマッチする最初の行をヒープページ内から特定すると、その他すべてのマッチする行は、おそらくすでに同じヒープページの中にあるので、ディスクアクセスを削減し、問い合わせが高速化されることになるからである。

データをクラスタ化するには 2 つの方法がある。1 つは、CLUSTER コマンドで、オリジナルのテーブルを指定したインデックス順に並べ替えることである。この方法は、巨大なテーブルの場合は遅くなる。これは、各行はヒープからインデックス順に取り出されるので、もしヒープテーブルが並んでいない場合は、エントリはランダムなページ上にあり、各行の移動の際にレコードを取り出すたびに 1 回のディスクアクセスが行われるからである。PostgreSQL はキャッシュを持ってはいるが、一般的に大きなテーブルはキャッシュの中には入りきれない。

もう 1 つの方法としては、SELECT ... INTO TABLE temp FROM ...ORDER BY ... を使用することがある。これは、ORDER BY の中で、インデックスにマッチさせるのに PostgreSQL のソートルーチンを使うので、並んでいないデータに対してはより早くなる。そしてそのあと古いテーブルを drop し、 ALTER TABLE RENAME で'temp' を古い名前にリネームし、the bbindexe を再作成する。ただ 1 つの問題は、oid が保存されないことである。これらのことから、ヒープデータのほとんどはすでに並び変わっており、存在するインデックスが使われるのであれば、CLUSTER の方が速いということになる。

/*
 * 従業員を彼らの給与属性を元にクラスタ化する
 */
create index 従業員_ind on 従業員 using btree (給与 int4_ops);

cluster 従業員_ind on 従業員

翻訳者

堀田 倫英 <hotta@net-newbie.com>