Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Jak najwydajniej przerzucić tabelę między bazami?
Forum PHP.pl > Forum > Bazy danych > MySQL
nexis
Mam dwie bazy danych, działające na tym samym serwerze. Pierwsza baza ma następującą tabelę:
  1. CREATE TABLE `sklep_parametr` (
  2. `produkt` varchar(32) NOT NULL,
  3. `nazwa` varchar(255) NOT NULL,
  4. `opis` varchar(255) NOT NULL,
  5. `jm` varchar(16) NOT NULL
  6. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;

którą chcę przerzucić do drugiej bazy danych o trochę odmiennej budowie tabeli:
  1. CREATE TABLE `parameter` (
  2. `product_code` varchar(255) collate utf8_polish_ci NOT NULL,
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `key` varchar(255) collate utf8_polish_ci NOT NULL,
  5. `value` varchar(255) collate utf8_polish_ci NOT NULL,
  6. PRIMARY KEY (`id`),
  7. KEY `product_code` (`product_code`)
  8. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;

Relacje mają być następujące:
product_code = produkt
id = (auto increment)
key = nazwa
value = opis

Jak zrobić taką kopię najwydajniej z poziomu PHP? Warto dodać, że tabela posiada ponad 250.000 wpisów!
phpion
Najwydajniej chyba byłoby zrzucić dane do pliku CSV, po czym wczytać je do nowej tabeli poprzez LOAD DATA. Kwestia tylko czy pole opis nie będzie tutaj problemem... Tak czy siak LOAD DATA jest pierońsko szybkie więc stawiałbym na tą funkcję.

PS: jeśli bazy są na tym samym serwerze* możesz wykonać INSERT INTO FROM SELECT - będziesz miał mniej zachodu, a i czas wykonania może być szybszy. Generalnie na czas przerzutu danych usunąłbym indeksy (używasz MyISAM więc o wyłączenie sprawdzania więzów integralności nie ma się co martwić).

* widzę, że są więc spróbowałbym tej opcji
nexis
Cytat(phpion @ 8.09.2009, 21:27:50 ) *
PS: jeśli bazy są na tym samym serwerze* możesz wykonać INSERT INTO FROM SELECT - będziesz miał mniej zachodu, a i czas wykonania może być szybszy. Generalnie na czas przerzutu danych usunąłbym indeksy (używasz MyISAM więc o wyłączenie sprawdzania więzów integralności nie ma się co martwić).

* widzę, że są więc spróbowałbym tej opcji

Zapomniałem dodać, że każda baza ma innego użytkownika, więc ten sposób chyba odpada.

Operacja ma się wykonywać docelowo co 24 godziny, więc chciałbym aby załatwił to skrypt PHP, odpalany przez CRON.
phpion
Cytat(nexis @ 8.09.2009, 22:47:31 ) *
Zapomniałem dodać, że każda baza ma innego użytkownika, więc ten sposób chyba odpada.

Nie możesz stworzyć dodatkowego użytkownika mającego dostęp do obu baz?

Cytat(nexis @ 8.09.2009, 22:47:31 ) *
Operacja ma się wykonywać docelowo co 24 godziny, więc chciałbym aby załatwił to skrypt PHP, odpalany przez CRON.

No to tym lepiej zrobić to w samym SQL. Możesz odpalić w CRONie bezpośrednio samo zapytanie SQL (bez ingerencji w PHP) lub skorzystać z EVENTów w MySQL (wiem, że są/powinny być, ale nigdy sam z nich nie korzystałem).
nexis
Cytat(phpion @ 9.09.2009, 06:29:09 ) *
Nie możesz stworzyć dodatkowego użytkownika mającego dostęp do obu baz?

Niestety aplikacja jest na hostingu współdzielonym (home.pl) i nie ma takiej możliwości. Czyli zostaje zrzut do pliku i wczytanie go w drugiej bazie? Jak w takim razie zmienić strukturę tabeli?
dr_bonzo
Cytat
Zapomniałem dodać, że każda baza ma innego użytkownika, więc ten sposób chyba odpada.

Nie ma to jak zapomniany *szczegolnie wazny* fragment specyfikacji...


A nie prosciej pobrac wszystkie rekordy i wstawic do drugiej tabeli? 2 polaczenia w php, jedna petelka i jazda?

Cytat
Jak w takim razie zmienić strukturę tabeli?

No jak to jak? ALTER TABLE...


--
edit:
no niby mozna wyeksportowac 1 tabele, wrzucic do bazki, i zmodyfikowac jej strukture - ale chcesz to robic za kazdym razem?
No i pozostaje problem autoincrement - nie wiem czy sam doda wartosci, po dodaniu nowej kolumny z AI.

Wydaje mi sie ze lepiej przygotowac docelowa tabele, i tylko przerzucac dane insertami.
nexis
Cytat(dr_bonzo @ 9.09.2009, 09:46:20 ) *
A nie prosciej pobrac wszystkie rekordy i wstawic do drugiej tabeli? 2 polaczenia w php, jedna petelka i jazda?

Dla ponad 250.000 rekordów w 30 sekund (timeout)? Jaki kod PHP proponujesz (mysql, mysqli, PDO)?
nospor
Cytat
Dla ponad 250.000 rekordów w 30 sekund (timeout)?

http://pl2.php.net/manual/pl/function.set-time-limit.php

poza tym kto ci kaze na raz to zrobic? Nie mozesz tego wykonywać porcjami?
dr_bonzo
Mozesz probowac wylaczyc timeout. Albo zapisywac gdzie skonczyles przerzucanie, a potem je wznowic.

Kod? Na pewno multi insert, tzn

INSERT INTO tabelka (........) VALUES (...), (...), (...), (...), (...), (...), (...), (...)

i pobaw sie iloscia rekordow, ostatnio uzyskiwalem najlepsze rezultaty dla ok 250 sztuk na 1 insert, no ale to zalezy bardzo od danych jakie wstawiasz.
nexis
Cytat(dr_bonzo @ 9.09.2009, 09:53:08 ) *
Mozesz probowac wylaczyc timeout.

Tak jak pisałem: hosting współdzielony na home.pl - nie ma możliwości wyłączenia timeout.
erix
Zawsze możesz spróbować - gdzieś czytałem, że operacje I/O nie są wliczane do limitu działania skryptów.

Poza tym, dlaczego nie zrobisz tego partiami, po - powiedzmy - 10 000 rekordów/wywołanie?
nospor
Cytat
Poza tym, dlaczego nie zrobisz tego partiami, po - powiedzmy - 10 000 rekordów/wywołanie?
Jestes juz 3 osobą która o to pyta. Moze ciebie nie zignoruje jak pozostałych smile.gif
nexis
Cytat(nospor @ 9.09.2009, 12:05:36 ) *
Jestes juz 3 osobą która o to pyta. Moze ciebie nie zignoruje jak pozostałych smile.gif

Jestem wdzięczny za wszelkie pomysły, ale przyznacie chyba rację, że łatwiej odpalić raz skrypt niż w kilku etapach. Na chwilę obecną skrypt wstawia ponad 270.000 rekordów w 57 sekund w paczkach po 5.000.
nospor
Cytat
ale przyznacie chyba rację, że łatwiej odpalić raz skrypt niż w kilku etapach
ale przyznasz chyba rację, ze jak ktoś sie ciebie o coś dopytuje/podrzuca pomysl to ze zwyklej kultury warto mu odpowiedziec, nawet jesli tenze pomysl masz juz w realizacji smile.gif
Poza tym jakbyś odpowiedział od razu, to nie musiałby się o to pytać dwie kolejne osoby.

Pewnie że lepiej zrobic wszystko za jednym zamachem, ale jak sie nie da to trzeba kombinować.
erix
Cytat
Jestem wdzięczny za wszelkie pomysły, ale przyznacie chyba rację, że łatwiej odpalić raz skrypt niż w kilku etapach

No to jak powiedział ~nospor - nie ma co się lubi, lubi się co się ma.

Tak nawiasem, przy backupowaniu forum też robiliśmy paczkami, bo wszystko naraz:
  1. byłoby poza kontrolą (przymrożone połączenie i od początku)
  2. przeciążęnie serwera, etc
  3. spora ilość danych (kilka razy tyle, co Twoich ;])

ale wszystko poszło nadzwyczaj gładko. :]
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.