2012-06-25 26 views
15

Czy istnieje bardziej skuteczny, mniej pracochłonny sposób kopiowania wszystkie rekordy z jednej tabeli do innego, który to robi:MySQL skutecznie skopiować wszystkie rekordy z jednej tabeli do drugiej

INSERT INTO product_backup SELECT * FROM product 

Zazwyczaj tabela product odbędzie około 50 000 rekordów. Obie tabele mają identyczną strukturę i zawierają 31 kolumn. Chciałbym zwrócić uwagę, że jest to nie mój projekt bazy danych, odziedziczyłem dotychczasowy system.

+5

I myśli, że to jest najlepszy sposób. W ten sposób zachowujesz także indeksy. –

+1

Prędkość jest prawie tak dobra, jak to tylko możliwe. Oczywiście można wstrzymać tworzenie indeksu na tabeli kopii zapasowej, dopóki wszystkie dane nie zostaną skopiowane, co znacznie zwiększy szybkość wstawiania. – fvu

+0

To interesujące, dzięki. Byłem ciekawy w kwestii kopiowania danych i zastanawiałem się, czy jest to albo drenaż bazy danych ("SELECT *" wyrzucił mnie, czy też zajmie dużo czasu proces ze względu na sposób konstruowania zapytania). Jeśli jest to dopuszczalny sposób kopiowania danych, to jest to w porządku. – crmpicco

Odpowiedz

9

Uważam, że jest to najlepszy sposób kopiowania rekordów z jednej tabeli do drugiej. W ten sposób zachowujesz także istniejące indeksy tabeli docelowej.

1

Nie sądzę, że będzie to warte na stół 50 tys., Ale: Jeśli masz zrzut bazy danych, możesz od niego ponownie załadować tabelę. Jak chcesz, aby załadować tablicę w innym można zmienić nazwę tabeli w zrzuci z polecenia sed: Tutaj masz jakieś wskazówki: http://blog.tsheets.com/2008/tips-tricks/mysql-restoring-a-single-table-from-a-huge-mysqldump-file.html

Alternatywą (w zależności od projektu) byłoby użyć wyzwalaczy na oryginalnych tablicach wstawia tak, aby zduplikowana tabela otrzymywała również dane.

Lepszą alternatywą byłoby stworzenie kolejnej instancji MySQL i uruchomienie jej w konfiguracji master-slave lub w trybie codziennego dump master/load slave.

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

To zajmie zrzut określonych tabel z opcją drop usunąć tabelę objąć istniejącymi podczas importowania go. następnie,

mysql db_name < filepath/file_name.sql 
+0

Powinienem dodać, że robię to w kodzie PHP. Zostanie to zrobione, zanim seria INSERT i UPDATE zostanie przeprowadzona w tabeli 'product', więc chciałbym to zrobić w PHP, a nie w funkcjach administracyjnych MySQL. – crmpicco

12

Jest tylko jedna rzecz, której brakuje. Szczególnie, jeśli używasz InnoDB, to chcesz jawnie dodać ORDER BY w instrukcji SELECT, aby zapewnić sobie wstawianie wierszy w kluczu podstawowym (skupione indeks) zamówienie:

INSERT INTO product_backup SELECT * FROM product ORDER BY product_id 

Rozważ usunięcie indeksów wtórnych na stole zapasowym, jeśli nie są potrzebne. To również zapisze trochę obciążenia na serwerze.

Wreszcie, jeśli używasz InnoDB, zmniejszyć liczbę blokad wierszy, które są wymagane i tylko jawnie zablokować obie tabele:

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

Rzeczy zamek prawdopodobnie nie będzie stanowić ogromną różnicę, jak blokowanie wierszy jest bardzo szybki (choć nie tak szybki jak blokady stołowe), ale od kiedy zapytałeś.

+0

Używam silnika MyISAM. Wspomniałem we wcześniejszym poście, że odziedziczyłem stary system, więc to MyISAM na razie. – crmpicco

+0

nie można zamówić, aby utworzyć drzewo indeksu, które jest niezbalansowane? W takim przypadku kolejność losowa może być lepsza dla klucza podstawowego? –

+0

@DannyStaple, drzewo jest płaskie podczas wstawiania do indeksu w porządku posortowanym za pomocą MyISAM. Poprawia to wydajność (bez konieczności odbudowywania indeksu), a także oszczędza miejsce. Od [dokumentacja MySQL] (http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html): „Gdy wiersze są wstawiane w posortowanych (jak wtedy, gdy używasz kolumny AUTO_INCREMENT) drzewo indeksów jest podzielone, tak aby węzeł wysoki zawierał tylko jeden klucz, co poprawia wykorzystanie przestrzeni w drzewie indeksów. " –

1

DROP tabela docelowa:

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

co, jeśli w tabeli docelowej znajdują się dane, które OP chce zachować i dodać do? – Martin

+0

po co upuszczać i tworzyć tabelę zamiast DELETE FROM destination_table; INSERT INTO destination_table WYBIERZ * Z produktu? Który z nich jest bardziej wydajny? –

Powiązane problemy