2012-06-25 17 views
15

C'è un più efficiente, modo meno faticoso di copiare tutti i record da un tavolo all'altro che facendo questo:MySQL in modo efficiente copiare tutti i record da un tavolo all'altro

INSERT INTO product_backup SELECT * FROM product 

In genere, la tabella product terrà circa 50.000 record. Entrambe le tabelle sono identiche nella struttura e contengono 31 colonne. Mi piacerebbe sottolineare che questo è non il mio design del database, ho ereditato un sistema legacy.

+5

I pensa che questo sia il modo migliore. In questo modo stai anche conservando gli indici. –

+1

Speedwise è il massimo. Ovviamente, è possibile rimandare la creazione dell'indice sulla tabella di backup fino a quando tutti i dati non sono stati copiati, il che aumenterà significativamente la velocità di inserimento. – fvu

+0

È interessante, grazie. Ero curioso riguardo alla copia dei dati e mi chiedevo se si trattasse di un drenaggio del database (il 'SELECT *' mi ha respinto, o se ci sarebbe voluto molto tempo per elaborare a causa del modo in cui la query è costruita). Se questo è un modo accettabile di copiare i dati, allora va bene. – crmpicco

risposta

9

Penso che questo sia il modo migliore per copiare i record da una tabella a un'altra tabella. In questo modo si conservano anche gli indici esistenti della tabella di destinazione.

1

Non penso che questo sia degno per un tavolo da 50k ma: Se si dispone del dump del database è possibile ricaricare una tabella da esso. Come si desidera caricare un tavolo in un altro si potrebbe cambiare il nome della tabella in discarica con un comando sed: Ecco alcuni suggerimenti: http://blog.tsheets.com/2008/tips-tricks/mysql-restoring-a-single-table-from-a-huge-mysqldump-file.html

Un'alternativa (a seconda del design) sarebbe quella di utilizzare i trigger sulla tabella originale inserisce in modo che anche la tabella duplicata riceva i dati.

E un'alternativa migliore sarebbe quella di creare un'altra istanza MySQL e eseguirla in una configurazione master-slave o in modalità master/slave di dumping giornaliero.

4
mysqldump -R --add-drop-table db_name table_name > filepath/file_name.sql 

questo richiederà una discarica di tabelle specificate con opzione di drop per eliminare la tabella exisiting quando si importa. quindi,

mysql db_name < filepath/file_name.sql 
+0

Avrei dovuto aggiungere che lo sto facendo nel codice PHP. Sarà fatto prima che una serie di INSERT e UPDATE vengano eseguiti sulla tabella 'product', quindi cercherò di farlo in codice PHP piuttosto che in funzioni di amministrazione di MySQL. – crmpicco

12

C'è solo una cosa che ti manca. Soprattutto, se si sta utilizzando InnoDB, è che si desidera aggiungere esplicitamente una clausola ORDER BY nell'istruzione SELECT per garantire che stai inserendo righe in chiave primaria (indice cluster) ordine:

INSERT INTO product_backup SELECT * FROM product ORDER BY product_id 

in considerazione la rimozione indici secondari sulla tabella di backup se non sono necessari. Ciò salverà anche un po 'di carico sul server.

Infine, se si sta utilizzando InnoDB, ridurre il numero di blocchi di riga che sono necessari e solo bloccano esplicitamente entrambe le tabelle:

LOCK TABLES product_backup WRITE; 
LOCK TABLES product_id READ; 
INSERT INTO product_backup SELECT * FROM product ORDER BY product_id; 
UNLOCK TABLES; 

La roba di bloccaggio probabilmente non farà una grande differenza, come chiusura di fila è molto veloce (anche se non veloce come le serrature da tavolo), ma da quando hai chiesto.

+0

Sto usando il motore MyISAM. Ho menzionato in un post precedente che ho ereditato un sistema legacy, quindi per il momento è MyISAM. – crmpicco

+0

non è possibile ordinare che crea un albero dell'indice sbilanciato? In tal caso, l'ordine casuale potrebbe essere migliore per la chiave primaria? –

+0

@DannyStaple, l'albero è piatto quando si inserisce in un indice nell'ordine ordinato con MyISAM. Questo migliora le prestazioni (non dover ricostruire l'indice), oltre a risparmiare spazio. Da [documentazione MySQL] (http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html): "Quando le righe vengono inserite in ordine (come quando si utilizza una colonna AUTO_INCREMENT), l'albero dell'indice è diviso in modo che il nodo alto contenga solo una chiave, migliorando l'utilizzo dello spazio nell'albero dell'indice. " –

1

DROP la tabella di destinazione:

DROP TABLE DESTINATION_TABLE; 
CREATE TABLE DESTINATION_TABLE AS (SELECT * FROM SOURCE_TABLE); 
+0

cosa succede se nella tabella di destinazione sono già presenti dati che OP desidera conservare e aggiungere? – Martin

+0

perché eliminare e creare tabella invece di DELETE FROM destination_table; INSERISCI IN destination_table SELECT * FROM product? Qual è più efficiente? –

Problemi correlati