データベースのネイティブなバルクロードパス(Postgres COPY、MySQL LOAD DATA)を使い、ファイルをチャンクに分割してインデックスと制約をしたへでロードし、その後インデックスを一度だけ再構築してマージします。そしてジョブ全体をにして、クラッシュしても行を重複させずに再開できるようにします。
100M-row CSV
│ split by byte offset
▼
[chunk 1] [chunk 2] ... [chunk N] N parallel workers
│ │ │
└──── COPY / LOAD DATA (no indexes) ────▶ staging_table (UNLOGGED)
│
rebuild indexes + validate
│
INSERT ... SELECT (upsert) into target
素朴な行ごとの INSERT は、ラウンドトリップ、パース、WAL/redo書き込み、インデックス更新を1億回支払います。各1msでも1日を超えます。バルクパスはこれらすべてを償却して勝ちます。COPY は1つのプロトコルメッセージで行をストリームし、WALをバッチ化し、ステートメントごとのプランニングをスキップします。実機では単一の COPY がINSERTの数千に対し10万〜50万行/秒を出します。
UNLOGGED はWALを完全にスキップ)にロードし、決してライブテーブルへ直接ロードしません。これでロードを読み手から隔離し、公開前に検証できます。CREATE INDEX を一度だけ。バルク(ソート済み)でのインデックス構築は1億の逐次更新よりはるかに安価です。COPY ストリームを実行します。スループットはディスクやWALを飽和させるまでI/OとCPUに応じてスケールします。「できるだけ多く」ではなく、Nをコア数/IOPSに合わせます。INSERT ... ON CONFLICT DO NOTHING/UPDATE(upsert)で公開し、再実行が決して二重挿入しないようにします。面接官は、あなたがバルクパスの存在と、なぜそれが桁違いに速いのかを知っているかを確認します。COPYの構文ではありません。良い:「COPYを使う」。優れた:「UNLOGGEDのステージングテーブルへCOPY、インデックスをドロップ、並列チャンク、後で再構築、upsertで公開、チャンクidで再開可能」。典型的な罠はINSERTのループ(またはORMの saveAll)で、何時間もかかって驚くこと。第2の罠は、ライブテーブルへ直接ロードして本番をブロックすることです。
maintenance_work_mem/一時領域が必要。1億行のインデックス構築はディスクにあふれえます。ジュニアからシニアまで、詳細な回答付きのIT面接質問ライブラリ。
寄付する