200 GBのサイズのデータと180 GBのサイズの6つのインデックスがテーブルにあります。 30%膨らんでいるので、不要なスペースを取り戻したいと思います。 job_id_id
xインデックスでクラスター化されています。
スペースを取り戻すには、cluster
コマンドまたはvacuum full
コマンドを使用する必要がありますか?
この2つのコマンドの違いは何ですか?
一部の列によるvacuum full
の順序はcluster
コマンドと同じですか?
両方のコマンドでインデックスが再作成されますか?
私の場合、どちらが速くなりますか?
PostgreSQLデータベースのバージョンは9.1です
CLUSTER
の機能を確認するために、基本的に最初の1000万の正の整数を含む以前の実験からの表を作成しました。私はすでにいくつかの行を削除し、他の列もありましたが、これらは実際のテーブルサイズにのみ影響するため、それほど興味深いものではありません。
まず、テーブルfka
でVACUUM FULL
を実行して、そのサイズを取得しました。
\dt+ fka
List of relations
Schema | Name | Type | Owner | Size | Description
--------+------+-------+----------+--------+-------------
public | fka | table | test | 338 MB |
次に、テーブルの最初からデータの物理的な順序を見てみましょう。
SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;
id | col1 | ctid
-----+------+---------
2 | 2 | (0,1)
3 | 3 | (0,2)
4 | 4 | (0,3)
5 | 5 | (0,4)
6 | 6 | (0,5)
次に、いくつかの行を削除します。
DELETE FROM fka WHERE id % 10 = 5;
--DELETE 1000000
この後、報告されたテーブルサイズは変更されませんでした。それでは、CLUSTER
の機能を見てみましょう。
CLUSTER fka USING fka_pkey;
SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;
id | col1 | ctid
-----+------+---------
2 | 2 | (0,1)
3 | 3 | (0,2)
4 | 4 | (0,3)
6 | 6 | (0,4)
7 | 7 | (0,5)
操作後、テーブルサイズは338 MBから296 MBに変更されました。ページ内のタプルの物理的な場所を説明するctid
列から、id = 5
に一致する行が以前あった場所にギャップがないこともわかります。
タプルが並べ替えられたため、正しい場所を指すようにインデックスが再作成されているはずです。
したがって、違いは、VACUUM FULL
が行を並べ替えないことです。私の知る限り、2つのコマンドが使用するメカニズムにはいくつかの違いがありますが、実際的な観点からは、これが主な(唯一の)違いのようです。
VACUUM FULL
は、テーブルの内容全体を余分なスペースのない新しいディスクファイルに書き換え、未使用のスペースをオペレーティングシステムに返すことができるようにします。このメソッドは、テーブルの新しいコピーを書き込み、操作が完了するまで古いコピーを解放しないため、追加のディスク容量も必要です。通常、これは、テーブル内から大量のスペースを回収する必要がある場合にのみ使用してください。
http://www.postgresql.org/docs/9.1/static/sql-vacuum.html
CLUSTER
は、index_nameで指定されたインデックスに基づいて、table_nameで指定されたテーブルをクラスター化するようにPostgreSQLに指示します。インデックスはすでにtable_nameで定義されている必要があります。テーブルがクラスター化されると、テーブルはインデックス情報に基づいて物理的に並べ替えられ、ACCESS EXCLUSIVEロックが獲得されます。
http://www.postgresql.org/docs/9.1/static/sql-cluster.html
また、intresting: is-a-reindex-required-after-cluster
しかし、おそらく必要なのは単純なREINDEX
だけで、インデックスのテーブルに格納されたデータを使用してインデックスを再構築し、インデックスの古いコピーを置き換えます。