web-dev-qa-db-ja.com

何百万ものINSERTステートメントを含む大きなSQLダンプのインポート

大きな.sqlファイル(解凍すると8.1GB)をPostgreSQLにインポートする必要があります。 \i /path/to/file.sqlを使用しようとしましたが、速度が遅すぎます。

どのようにインポートを高速化しますか?このデータを毎週インポートする必要があります。

最初の2000行はここにあります 、一方 圧縮された1 GBのダンプはここにあります

--
-- PostgreSQL database dump
--

-- Dumped from database version 9.5.3
-- Dumped by pg_dump version 9.5.2

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;

--
-- Name: rpo; Type: SCHEMA; Schema: -; Owner: -
--

それが私がデータを取得できる唯一の方法です。完全なファイルには約があります。 38,000,000行。インポートを高速化するにはどうすればよいですか?

6
Ondrej Vrabel

このダンプは個別のステートメントとしてダンプされました(pg_dump --insertsを使用)

INSERT INTO esa2010_codes VALUES (11002, 'Národn
INSERT INTO esa2010_codes VALUES (11003, 'Nefina
INSERT INTO esa2010_codes VALUES (12502, 'Národn
INSERT INTO esa2010_codes VALUES (11001, 'Verejn
INSERT INTO esa2010_codes VALUES (12602, 'Národn
INSERT INTO esa2010_codes VALUES (12603, 'Finanč
INSERT INTO esa2010_codes VALUES (12503, 'Ostatn

これは遅いと記載されています(man pg_dumpから)

--insertsINSERTではなく)COPYコマンドとしてデータをダンプします。 これにより、復元が非常に遅くなります;主に、PostgreSQL以外のデータベースにロードできるダンプを作成するのに役立ちます。ただし、このオプションは行ごとに個別のコマンドを生成するため、行の再読み込みでエラーが発生すると、テーブルの内容全体ではなく、その行のみが失われます。列の順序を変更した場合、復元が完全に失敗する可能性があることに注意してください。 --column-insertsオプションは、列の順序の変更に対して安全ですが、さらに遅くなります。

それがとても遅い理由です。あなたがしたいことは、いくつかの 耐久性設定 、特にsynchronous_commitをオフにすることですが、fsyncも役立ちます

これを行うには、\i file.sqlを実行する前に次のコマンドを実行します。

SET synchronous_commit TO off;

それはそれをスピードアップするために多くのことをします。完了したら、耐久性オプションをオンに戻すことを忘れないでください。設定してから数時間で完了します。より高速が必要な場合でも、データを取得するまで、クラスターでfsyncfull_page_writesをオフにするのをためらわないでください。ただし、DBに必要なデータがある場合は、それを行いませんその中で、またはそれが生産だった場合。最後の注意として、速度が必要で、これが本番DBである場合は、独自のコピーですべてを実行し、pg_dumpのデフォルトオプションでダンプすることができます。これにより、はるかに高速にロードできます。

14
Evan Carroll

別のオプションは、1つのトランザクションでインポートを実行することです(可能な場合)。

BEGIN;
\i dump.sql
COMMIT;

PostgreSQLはデフォルトで自動コミットモードで実行されています。つまり、すべてのコマンドがcommitで終了し、コミットはfsyncで終了します(fsyncはかなり低速です)。非同期のコミット(Evan Carrollの応答)によって削減することも、明示的なトランザクションによって1つに削減することもできます。

その他の可能性は、参照整合性のチェックを無効にすることです(使用されている場合)。ダンプは一貫していて正しいので、このバリアントは可能です。コマンドALTER TABLE xx DISABLE TRIGGER ALLの詳細を確認できます。

ファイルのソースはpg_dumpです。最も単純な高速化は、ダンプの作成時にいくつかのオプションを使用することで実現できます。

  1. オプション--insertsは使用しないでください。コピー形式は復元のために大幅に高速です

  2. オプション--disable-triggersを使用してRIチェックを無効にします(正しいデータが必要です)

  3. カスタム形式の-Fオプションを使用できます。次に、pg_restoreを使用して、インデックスの復元と構築​​(最も遅い操作)を並行して行うことができます。

2
Pavel Stehule