web-dev-qa-db-ja.com

ON DUPLICATE KEY UPDATEを使用したMySQL LOAD DATA INFILE

大量のデータをMySQLにロードする場合、 LOAD DATA INFILE は断然最速のオプションです。残念ながら、これはINSERT IGNOREまたはREPLACEが機能する方法で使用できますが、ON DUPLICATE KEY UPDATEは現在サポートされていません。

しかしながら、 ON DUPLICATE KEY UPDATEにはREPLACEよりも利点があります。後者は、重複が存在する場合に削除と挿入を行います。これにより、キー管理のオーバーヘッドが発生します。また、自動インクリメントIDは置換時に同じままになりません。

どのようにすることができます ON DUPLICATE KEY UPDATE LOAD DATA INFILEの使用時にエミュレートされますか?

39
Jan

これらの手順を使用して、この機能をエミュレートできます。

1)新しい一時テーブルを作成します。

CREATE TEMPORARY TABLE temporary_table LIKE target_table;

2)オプションで、すべてのインデックスを一時テーブルから削除して、処理を高速化します。

SHOW INDEX FROM temporary_table;
DROP INDEX `PRIMARY` ON temporary_table;
DROP INDEX `some_other_index` ON temporary_table;

3)CSVを一時テーブルにロードします

LOAD DATA INFILE 'your_file.csv'
INTO TABLE temporary_table
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
(field1, field2);

4)ON DUPLICATE KEY UPDATEを使用してデータをコピーします

SHOW COLUMNS FROM target_table;
INSERT INTO target_table
SELECT * FROM temporary_table
ON DUPLICATE KEY UPDATE field1 = VALUES(field1), field2 = VALUES(field2);

5)一時テーブルを削除する

DROP TEMPORARY TABLE temporary_table;

SHOW INDEX FROMおよびSHOW COLUMNS FROMを使用すると、このプロセスは任意のテーブルに対して自動化できます。

81
Jan

(Jan)が共有するプロシージャの最初の(2ステップ)を以下の単一クエリに置き換えることができます。

1)および2)インデックスなしで同じ参照構造を持つ新しいテーブルを作成できます。

CREATE TEMPORARY TABLE temporary_table SELECT * FROM target_table WHERE 1 = 0;

の代わりに..

1)新しい一時テーブルを作成します。

CREATE TEMPORARY TABLE temporary_table LIKE target_table;

2)オプションで、すべてのインデックスを一時テーブルから削除して、処理を高速化します。

Temporary_tableからSHOW INDEX; DROP INDEX PRIMARY ON temporary_table;ドロップインデックスsome_other_index ON temporary_table;

3
Suneet Khurana