2013-03-07 13 views
29

Per il caricamento di enormi quantità di dati in MySQL, l'opzione più veloce è LOAD DATA INFILE. Sfortunatamente, mentre questo può essere usato in un modo INSERT IGNORE o REPLACE funziona, ON DUPLICATE KEY UPDATE non è attualmente supportato.MySQL CARICARE DATI INFILA con ON DUPLICATE KEY UPDATE

Tuttavia, ON DUPLICATE KEY UPDATE presenta vantaggi rispetto a REPLACE. Quest'ultimo fa una cancellazione e un inserto quando esiste un duplicato. Ciò comporta un sovraccarico per la gestione delle chiavi. Inoltre, gli ID autoincrement non rimarranno gli stessi su una sostituzione.

Come si può emulare ON DUPLICATE KEY UPDATE quando si utilizza LOAD DATA INFILE?

risposta

60

Questi passaggi possono essere usati per emulare questa funzionalità:

1) Creare una nuova tabella temporanea.

CREATE TEMPORARY TABLE temporary_table LIKE target_table; 

2) Facoltativamente, rilasciare tutti gli indici dalla tabella temporanea per velocizzare le operazioni.

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

3) Caricare il CSV nella tabella temporanea

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

4) copiare i dati utilizzando 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) Rimuovere la tabella temporanea

DROP TEMPORARY TABLE temporary_table; 

utilizzando SHOW INDEX FROM e SHOW COLUMNS FROM questo processo può essere automatizzato per qualsiasi tabella specificata.

+3

Suggerisco piuttosto di usare 'INSERT INTO target_table SELECT coloumn_name1, coloumn_name1 FROM temporary_table' perché * includerà la chiave primaria e causerà gli articoli con la stessa chiave primaria (nel caso di una chiave primaria auto_increment) nella tabella principale da aggiornare , altrimenti questo ha funzionato per me! – JonoCoetzee

+0

Grazie per la risposta, ha funzionato per me dopo un po 'di giocoleria SQL. Il mio SQL-fu è molto arrugginito, bello imparare tecniche pulite come questa. – Chubas

+0

Grazie anche da qui - funziona brillantemente - non pensavo fosse possibile fare un ON DUPLICATE KEY con LOAD DATA INFILE, quindi mai provato prima. – Shaun

1

siamo in grado di sostituire prima (due passaggi) con sotto singola query nella procedura condivisa da (Jan).

1) e 2) possiamo creare una nuova tabella con la stessa struttura di riferimento e senza indici.

CREA TABELLA TEMPORANEA temporary_table SELECT * FROM target_table WHERE 1 = 0;

Invece di ..

1) Creare una nuova tabella temporanea.

CREA TABELLA TEMPORANEA temporanea come LIKE target_table;

2) Facoltativamente, rilasciare tutti gli indici dalla tabella temporanea per velocizzare le operazioni.

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