500 万を超えるエントリを含む Postgre SQL データベース テーブルがあります。100,000 エントリを含む CSV ファイルもあります。
CSV ファイルのデータに関連する DB からデータを取得するには、クエリを実行する必要があります。
しかし、皆さんの理解と私自身の経験によると、この種のクエリは完了するまでに時間がかかります。(私の推測では6時間以上)
最新の調査結果とツールによると、これと同じタスクを実行するためのより優れた高速なソリューションはありますか?
500 万を超えるエントリを含む Postgre SQL データベース テーブルがあります。100,000 エントリを含む CSV ファイルもあります。
CSV ファイルのデータに関連する DB からデータを取得するには、クエリを実行する必要があります。
しかし、皆さんの理解と私自身の経験によると、この種のクエリは完了するまでに時間がかかります。(私の推測では6時間以上)
最新の調査結果とツールによると、これと同じタスクを実行するためのより優れた高速なソリューションはありますか?
高速レーン: CSV ファイルの構造に一致する一時テーブルを作成し(便宜上、既存のテーブルをテンプレートとして使用する可能性があります)、次を使用しますCOPY
。
CREATE TEMP TABLE tmp(email text);
COPY tmp FROM 'path/to/file.csv';
ANALYZE tmp; -- do that for bigger tables!
CSV 内のメールは一意であると想定していますが、指定していません。そうでない場合は、一意にします。
CREATE TEMP TABLE tmp0
SELECT DISTINCT email
FROM tmp
ORDER BY email; -- ORDER BY cheap in combination with DISTINCT ..
-- .. may or may not improve performance additionally.
DROP TABLE tmp;
ALTER TABLE tmp0 RENAME TO tmp;
あなたの特定のケースでは、電子メールの一意のインデックスが適切です。データをロードしてサニタイズした後にインデックスを作成する方がはるかに効率的です。このようにCOPY
して、重複があった場合に一意の違反で救済することも防ぎます。
CREATE UNIQUE INDEX tmp_email_idx ON tmp (email);
よく考えてみると、大きなテーブルを更新するだけなら、一時テーブルにインデックスはまったく必要ありません。順次読まれます。
はい DB テーブルは主キーを使用して索引付けされます。
この場合の唯一の関連インデックス:
CREATE INDEX tbl_email_idx ON tbl (email);
CREATE UNIQUE INDEX ...
できれば作ってください。
後のコメントで詳しく説明されているようにテーブルを更新するには:
UPDATE tbl t
SET ...
FROM tmp
WHERE t.email = tmp.email;
これらはすべて、plpgsql または sql 関数に簡単にラップできます。ファイル名をパラメータ化する場合は、plpgsql 関数で動的 SQL を使用する必要が
あることに注意してください。COPY
EXECUTE
デフォルトでは、一時テーブルはセッションの最後に自動的に削除されます。
関連する回答:
PostreSQL で新しい行のみを一括挿入する方法
私があなたを正しく理解していれば、いくつかのフィールドを持つ CSV ファイルがあり、PostgreSQL テーブルを検索するために使用される KEY が含まれています。
このタスクに使用できるプログラミング言語はわかりませんが、一般に、速度の問題を解決する必要があります。
最初の方法、プログラミング:
2 番目の方法、自然な sql:
選択する方法は、実際のタスクによって異なります。たとえば、私の経験では、価格表をデータベースにロードするためのインターフェースを作成する必要があり、実際にロードする前に、インポートされた XLS ファイルを「現在の」価格と「新しい」価格に関する情報とともに表示する必要がありました。ページネーションが必要なXLSファイルのサイズが大きいため、KEY IN(1,2,3,4,5,6)のバリアントが最適です。