Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Przeniesienie danych z plików do MySQL
Forum PHP.pl > Forum > Przedszkole
d0m1n1k_
Witam,
od jakiegoś czasu przymierzam się do migracji z plików na bazę danych jednego z moich pierwszych projektów.
Serwis w tym czasie nagromadził dość dużo cennych dla mnie danych i dorobił się prawie 18 GB plików tekstowych.

Dane są "ładnie" wprowadzone.
Kwestia przenoszenia do MySQL przebiega bez zgrzytów.
Ale martwi mnie sprawa szybkości.
Rekordów jest blisko 800 mln.

Poniższy skrypt mieli dość wolno, średnio 50.000 rekordów na godzinę.
Serwer jest domowy - tzn. laptop z 4GB ramu i Celeronem 2.16 Ghz...
Przy tym tempie to do przyszłego roku nie zdążę (wychodzi jakieś 16.000 godzin - 666 dni) a czas na uczelni zaczyna mnie gonić...

  1. <?php
  2.  
  3. DEFINE ('DB_USER','****');
  4. DEFINE ('DB_PASS','****');
  5. DEFINE ('DB_HOST','****');
  6. DEFINE ('DB_NAME','****');
  7.  
  8. $connection = mysql_connect (DB_HOST, DB_USER, DB_PASS) OR die
  9. ('Error - nie połączono z bazą danych<br />' . mysql_error() );
  10. mysql_select_db (DB_NAME) OR die ('Error - nie wybrano bazy danych<br />' . mysql_error() );
  11. $set_typ_coding = mysql_query("SET NAMES 'utf8'");
  12.  
  13.  
  14. $m = 0; //Liczba powtórek
  15.  
  16. if(isset($_GET['id'])){
  17. $numer = $_GET['id'];
  18.  
  19. echo "Dotyczy pliku: fizyka_" . $numer . ".txt<br />";
  20.  
  21. $dane = file('pliki/fizyka_' . $numer . '.txt');
  22. for($i=0;$max=count($dane),$i<$max;$i++){
  23. list($old_dane) = explode(';',$dane[$i]);
  24.  
  25. $check_stats = mysql_query("SELECT `statt` FROM `stare_repozytorium` WHERE `statt` = '$old_dane'");
  26. if(mysql_num_rows($check_stats) > 0){
  27. $m++;
  28. }else{
  29. $query = mysql_query("INSERT INTO `stare_repozytorium` (`id`, `statt`, `status`, `addeddate`) VALUES (NULL, '$old_dane', '0', NOW())");
  30. }
  31.  
  32. }
  33.  
  34. echo "Duplikatów: <b><font color=\"red\">" . $m . "</font></b>";
  35.  
  36. }else{
  37. echo "Nie wybrano id pliku";
  38. }
  39.  
  40. ?>


Dla stabilności mojej pracy - przy "odpalaniu" potrafi przywiesić kompa na minutę - każdy plik jest wybierany przeze mnie ręcznie ($_GET['id']).
Bardzo proszę, czy może mi ktoś podpowiedzieć - co mogę zrobić aby migracja przebiegła zdecydowanie szybciej?
mmmmmmm
LOAD + help
tomxx
Cytat
facepalmxd.gif
Tuminure
// Bazuję na moim doświadczeniu/wiedzy, nie na faktycznych benchmarkach. Umieszczone w kolejności, od której ja bym zaczął optymalizować kod.

  1. $check_stats = mysql_query("SELECT `statt` FROM `stare_repozytorium` WHERE `statt` = '$old_dane'");
  2. if(mysql_num_rows($check_stats) > 0){
  3. $m++;
  4. }else{
  5. $query = mysql_query("INSERT INTO `stare_repozytorium` (`id`, `statt`, `status`, `addeddate`) VALUES (NULL, '$old_dane', '0', NOW())");
  6. }
Select, a potem insert działa wolniej niż "insert ignore", który wymaga klucza unikalnego w tabeli. Jeżeli to możliwe to dodawaj wiele wpisów jednym insertem.

  1. for($i=0;$max=count($dane),$i<$max;$i++){
Wyrzuć tego counta przed fora. Obecnie ten count sprawdza ilość elementów przy każdej iteracji.

  1. $dane = file('pliki/fizyka_' . $numer . '.txt');
file_get_contents działa minimalnie szybciej. Być może warto przepisać kod, aby korzystać z tej funkcji.

  1. DEFINE ('DB_USER','****');
  2. DEFINE ('DB_PASS','****');
  3. DEFINE ('DB_HOST','****');
  4. DEFINE ('DB_NAME','****');
Zamiast definiować stałe, wpisz wartości po prostu do kodu. Mniej czytelnie, złe praktyki i takie tam ale znowu troszkę szybciej.

Wyrzuć echo.
d0m1n1k_
Cytat(mmmmmmm @ 22.06.2015, 07:07:23 ) *
LOAD + help


Może jakieś rozwinięcie tematu?

Cytat(tomxx @ 22.06.2015, 07:11:49 ) *
facepalmxd.gif


Jak wyżej - czyżbym stosował aż tak zamierzchłe techniki, które nie powinny widzieć światła dziennego w naszych mrocznych czasach? Co w tym takiego strasznego?

---------------------------------------------------
Tuminure

Nigdy nie spotkałem się ze składnią INSERT IGNORE.
Tabela posiada dwa indexy: id - primary, statt - unique
Jak wykorzystać tą składnię aby nie przerywała pętli aż do zakończenia wprowadzania danych?

Count już wyrzucony w fora.

file_get_contents ładuje plik do stringa, a file do tablicy - wolę tak to pozostawić.

Za to co otrzymałem od Ciebie, dziękuję!
Ale proszę o więcej :-)
memory
Cytat(d0m1n1k_ @ 22.06.2015, 11:09:19 ) *
Może jakieś rozwinięcie tematu?

google bulk insert mysql
d0m1n1k_
Kod zoptymalizowany i przeniesiony na serwer w firmie (na ssd, po cichu, będzie pracować nocami).
Wczoraj o 22:30 dodałem bazę, skrypt i pliki na ftp'a oraz czynność do harmonogramu zadań.
Od północy do siódmej rano, z nieco poniżej miliona rekordów na starcie, dziś po przyjściu do pracy było już 26.000.004 :-)
Maksymalnie miesiąc nocek i będzie wykonane :-)
Serwer w końcu ciągle na chodzie, a w nocy jego obciążenie nie przekracza 2%.


Dla zainteresowanych:
Laptop (Lenovo G50): Celeron N2840 2x2.16Ghz, 4GB RAM, 500GB SATAIII - wydajność przy pełnym obciążeniu ok. 50.000 rekordów / godzinę;
Serwer (Dell PE1950): 2 x Xeon DualCore 5150 2x2.66GHz, 16GB RAM, 2x60GB SSD SATAIII->SAS - wydajność przy limicie do 25% CPU i 8GB RAM ok. 2.750.000 rekordów / godzinę;

Najlepsze, że taki serwer (poza dyskami 2 x ) kosztuje mniej jak laptop i mógłby przerobić nawet 10M rekordów na godzinę nie przepracowując się...
prz3kus
Dziwne to troche, a co tutaj jest wąskim gardłem prcek(mieli teraz na 100%)?
d0m1n1k_
Nie jestem pewien co było wąskim gardłem... może sam fakt, że laptop jest laptopem ;-)
Na SSD grzeje aż miło, tylko zastanawia mnie jedno - gdzie mogę sprawdzić jaki jest limit bazy danych / tabeli? Obecnie jest już 50.000.000 wpisów i blisko 6GB danych.

Chciałem zrobić backup i...
  1. Brak eksportu do sql
  2. export.php: Brakuje parametru: what
  3. export.php: Brakuje parametru: export_type
  4. Po wejściu do zakładki Struktura, nie widać struktury bazy danych (kolumn) a jedynie możliwe działania oraz informacje o wykorzystanej przestrzeni i statystyki wiersza...
  5. Po wejściu do zakładaki Wstaw niema pól do których mógłbym dodać ręcznie dodatkowe wpisy...


Dla jasności typ bazy danych to InnoDB
Wie może ktoś co jest grane?
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.