1

非常に大きな xml ファイルを mysql db にインポートする速度を上げたいので、すべてのクエリを SQL ファイルにダンプし、コンソールで実行することにしました。

しかし、私の問題は、すべてのデータを単純に挿入できないことです。

一部のテーブルがリンクされているため、非常に高速LOAD DATA INFILEな機能を使用できません。だから私はSQLファイルにクエリを入れたいのですが、いくつかの制御操作が必要です。

そのIDを使用して別のテーブルにデータを追加できるようにするために、そのID(主キーとして)が必要なデータセットがあります。

だから私がmysqlコンソールで試したのはこれです:

INSERT IGNORE INTO tableA VALUES ( A, B, C);
SET @id = LAST_INSERT_ID();
IF( @id, SELECT 1, SELECT id INTO @id FROM tableA WHERE a=A and b=B and c=C);
INSERT INTO tableB VALUES ( @id, B, C);

明らかに IF ステートメントは機能しません。「SELECT IF」でのみ機能します。

私がやろうとしているのは、INSERT IGNORE を使用してデータセットを tableA に追加することです。そのため、重複したエラーは無視されます。新しい行を追加する場合、LAST_INSERT_ID() で @id を取得します。重複する @id がある場合は空ですが、IF チェックでその重複を選択して @a に入れるので、いずれにしても@id セット。次に、@id を使用してデータを tableB に配置し、正しいリンクを作成します。

このワークフローを IF で実行する可能性はありますか? LOAD DATA INFILE を使用するための単純な CSV を作成できないため、いくつかのチェックを行う必要があるリンク テーブルがあるため、SQL を生成するのが最善だと思います。

私の XML ファイルは 20 ~ 25GB ほどの大きさです。私の perl スクリプトは、すべてのチェックを実行してデータベースにインポートするのに 3 週間ほどかかりますが、実行するすべての mysql クエリのために非常に遅くなります。クエリ フローを制御できれば、perl スクリプトのすべてのチェックを使用して何百万ものクエリを実行する代わりに、大きな SQL ファイルを作成できます。

これが可能であることを教えてください。

4

1 に答える 1

1

あなたがそれをする必要があるかどうかはわかりません。tableA.atableA.b、およびtableA.cすべてが を決定する場合tableA.id、行のエントリが成功したかどうかに関係なく、次のことができるはずです。

INSERT IGNORE INTO tableA VALUES (A, B, C);
INSERT INTO tableB SELECT id, B, C FROM tableA WHERE a=A AND b=B AND c=C;

これは、投稿したクエリとまったく同じではないことを認識しています。大きな違いは、行が に実際に適切に挿入されている場合tableA(つまり、重複行エラーがない場合)、上記のステートメントは1の最初のフィールドに の値を挿入しないことtableBです。それが本当に必要な場合は、次のように動作するはずです。

INSERT IGNORE INTO tableA VALUES (A, B, C);
SET @id = LAST_INSERT_ID();
INSERT INTO tableB SELECT IF(@id IS NOT NULL, 1, id)
                     FROM tableA
                    WHERE a=A AND b=B AND c=C;

そして、最後に成功した挿入の実際の自動インクリメント値ではなく、それLAST_INSERT_ID()が返されると想定しています。NULL実際の動作は確認していません。

于 2013-02-11T02:18:33.317 に答える