3

libpqxx を使用して、大量のデータ (約 7.000.000 エントリ) を PostgreSQL データベースに一括ロードする必要がありますデータベースにデータを入力する方法に関するドキュメントを読みましたが、私の場合にこれを使用する方法がわかりません。まず、ファイルを使用できないため、データベース上のCOPYは論外です。また、ロードしているデータベースとテーブルは、インポート中に機能する必要があります。

シナリオは次のとおりです。すべてのデータ (既存のエントリを含む) を含むファイルを別のアプリケーションから定期的に (約 1 か月に 1 回) 取得します。エントリの量が多いため、各エントリの存在を確認することはできず、(前処理後に) 新しいデータを一括挿入するだけです。

現在、これを処理するために、新しいテーブルを作成し、libpqxx のテーブルライターを使用して (トランザクションなしで) データを挿入し、トランザクションで古いテーブルの名前を変更し、新しいテーブルを正しい場所に変更します。

また、これは 1 つのテーブルに対してだけでなく、レイアウトが異なる複数のテーブルに対して行う必要があります。したがって、テーブルの書き込みと日付の解析を分離しようとしました。ここで、テーブルの作成を除外する必要があります。このために私は

create temporary table foo_temp (like foo including indexes including defaults including constraints );

このようにして、次のようなテーブルが得られ、foo実際に書いている場所のレイアウトを知る必要はありません。ただし、これにより、インデックスと制約を含むテーブルが生成され、上記のガイドでは、インデックスによって一括挿入が遅くなるという問題が残ります。ただし、インデックスと制約を削除した場合 (または最初にコピーしなかった場合) は、元のテーブルに設定されていたのと同じ方法で後で再作成する方法が必要です。

これを迅速に処理する方法に関する良いヒントはありますか?

編集:

関連する側面: 先ほど気付いたデータベースをいじってみると、CREATE TABLE上記は外部キー制約をコピーしないため、これらも手動で指定する必要があるようです。または、これらを他のすべての制約と一緒に処理する方法はありますか?

4

3 に答える 3

2

次の戦略を使用して、インデックス作成と制約の作成により、1 秒あたり 100000 回以上の挿入を達成します。 1. 最初の接続で、親を継承するテーブルを作成し、PQputCopyData を使用してバイナリ モードでデータをコピーします。2. インデックスの作成には別の接続をいくつか使用します。PostgreSQL はクライアントごとに 1 つのスレッドを作成するため、マルチコアの利点を利用するには、複数の接続を使用する必要があります。

スレッドセーフ キューなどを使用するか、PostgreSQL NOTIFY を使用して、アプリケーション内のインデックス スレッドにデータを送信できます。

于 2011-08-21T06:40:01.843 に答える
1

COPY を使用するために外部ファイルは必要ありません。「STDIN」からコピーできます。「STDIN 入力がクライアント アプリケーションからのものであることを指定します。」

たとえば、pg_dumpallwhich を使用すると、既存のデータで COPY を使用/フォーマットする方法が示されます。

を使用しPQputCopyDataて、必要なバルク データを PostgreSQL サーバーに送信できます。

http://www.postgresql.org/docs/9.0/interactive/libpq-copy.html#LIBPQ-COPY-SEND

于 2011-06-07T22:07:31.003 に答える
1

インデックスと制約を参照する pg_index と pg_constraint テーブルがあります。(前者は完全な詳細を取得するために pg_class との結合を必要とします。) 詳細についてはpg_catalogを参照してください。

後者を使用して、一括挿入/更新後に必要なインデックス定義などを取得できます。

于 2011-06-07T21:50:50.387 に答える