大量のデータをMySQLにロードする場合、 LOAD DATA INFILE は断然最速のオプションです。残念ながら、これはINSERT IGNOREまたはREPLACEが機能する方法で使用できますが、ON DUPLICATE KEY UPDATEは現在サポートされていません。
しかしながら、 ON DUPLICATE KEY UPDATE
にはREPLACE
よりも利点があります。後者は、重複が存在する場合に削除と挿入を行います。これにより、キー管理のオーバーヘッドが発生します。また、自動インクリメントIDは置換時に同じままになりません。
どのようにすることができます ON DUPLICATE KEY UPDATE
LOAD DATA INFILEの使用時にエミュレートされますか?
これらの手順を使用して、この機能をエミュレートできます。
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
を使用すると、このプロセスは任意のテーブルに対して自動化できます。
(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;