VACUUM FULLとCLUSTERのPostgreSQLの違い


13

200 GBのサイズがデータで占められ、180 GBのサイズが6つのインデックスで占められているテーブルがあります。それは30%肥大化していますので、それによって占有されている不要なスペースを回収したいと思います。job_id_idxインデックスでクラスター化されます。

スペースを再利用するには、clusterコマンドまたはvacuum fullコマンドを使用する必要がありますか?

  1. この2つのコマンドの違いは何ですか?

  2. vacuum fullある列の順序はclusterコマンドと同じですか?

  3. 両方のコマンドでインデックスが再作成されますか?

  4. 私の場合、どちらが速くなりますか?

PostgreSQLデータベースのバージョンは9.1です


1
はい、インデックスは再作成されます。どちらが速いかは、いくつかのことによって決まります。しかし、1つ確かなことがあります。「列ごとの完全注文」のようなものはありません。
dezso

1
また、VACUUMはトランザクション内で実行できないため、多くの場合、CLUSTERは同様の結果を生成するより優れた代替(場合によっては唯一の代替)になります。
oᴉɹǝɥɔ

回答:


8

何をCLUSTER行うかを確認するために、基本的に最初の1,000万個の正の整数を含む以前の実験のテーブルを使用しました。すでにいくつかの行を削除し、他の列もありますが、これらは実際のテーブルサイズにのみ影響するため、それほど興味深いものではありません。

まず、VACUUM FULLテーブルfkaで実行した後、そのサイズを取りました。

\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つのコマンドが使用するメカニズムには多少の違いがありますが、実際的な観点からは、これが主な(唯一の)違いのようです。


ctid列が何であるかはわかりませんでした。テーブル内の行の物理的な場所を記述するシステム列であることがわかりました。postgresql.org/docs/current/ddl-system-columns.html
Gajus

8

VACUUM FULLテーブルの内容全体を余分なスペースなしで新しいディスクファイルに書き換え、未使用のスペースをオペレーティングシステムに戻すことができます。この方法では、テーブルの新しいコピーを書き込み、操作が完了するまで古いコピーを解放しないため、追加のディスク領域も必要です。通常、これは、テーブル内から大量のスペースを再利用する必要がある場合にのみ使用してください。

http://www.postgresql.org/docs/9.1/static/sql-vacuum.html

CLUSTERindex_nameで指定されたインデックスに基づいてtable_nameで指定されたテーブルをクラスター化するようにPostgreSQLに指示します。インデックスは、table_nameで既に定義されている必要があります。テーブルがクラスター化されると、インデックス情報に基づいて物理的に並べ替えられ、ACCESS EXCLUSIVEロックが取得されます。

http://www.postgresql.org/docs/9.1/static/sql-cluster.html

また、興味深い:is-a-reindex-required-after-cluster

ただし、必要なのはREINDEX、インデックスの古いコピーを置き換えて、インデックスのテーブルに格納されているデータを使用してインデックスを再構築するだけです。

http://www.postgresql.org/docs/9.1/static/sql-reindex.html


1
わあ!REINDEXについての素晴らしいヒントも!私はVACUUMとCLUSTERの両方でいくつかのテーブルを縮小しており(ライブを行うための時間と影響を比較しようとしています)、今では私の最大のオブジェクトは実際にはインデックスです。
マイク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.