web-dev-qa-db-ja.com

Postgresでインデックスを作成する最も効率的な方法

データのロードが完了した後または前にインデックスを作成する方が効率的ですか、それとも問題ではありませんか?

たとえば、Postgres 8.4 DBに読み込むファイルが500個あるとします。使用できる2つのインデックス作成シナリオを以下に示します。

  1. テーブルの作成時にインデックスを作成し、各ファイルをテーブルにロードします。または
  2. すべてのファイルがテーブルにロードされた後にインデックスを作成します。

テーブルデータ自体は約45ギガバイトです。インデックスは約12ギガバイトです。標準インデックスを使用しています。次のように作成されます。

CREATE INDEX idx_name ON table_name (column_name);

データの読み込みでは COPY FROM を使用しています。

すべてのファイルが読み込まれると、テーブルで更新、削除、または追加の読み込みは行われません(1日分のデータは変更されません)。それで、どのシナリオが最も効率的かを尋ねたいと思いましたか?最初のテストでは、すべてのファイルを読み込んでからインデックス(シナリオ2)を作成する方が速いことを示しているようですが、2つのアプローチの科学的な比較は行っていません。

43
user1356386

あなたの観察は正しいです-最初にデータをロードしてからインデックスを作成する方がはるかに効率的です。この理由は、挿入中のインデックスの更新が高価だからです。すべてのデータが存在した後にインデックスを作成すると、はるかに高速になります。

さらに先に進みます-大量のデータを既存のインデックス付きテーブルにインポートする必要がある場合、多くの場合、最初に既存のインデックスを削除し、データをインポートしてからインデックスを再作成する方が効率的です。

インポート後にインデックスを作成する場合のマイナス面の1つは、テーブルをロックする必要があることです。これには時間がかかる場合があります(逆のシナリオではロックされません)。ただし、PostgreSQL 8.2以降では、 CREATE INDEX CONCURRENTLY を使用できます。これは、インデックス作成中にテーブルをロックしません(いくつかの注意事項があります)。

72
mvp