Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MySQL][PHP] Przeniesienie danych z plików do MySQL, Kwestia szybkości dla INSERT
d0m1n1k_
post
Post #1





Grupa: Zarejestrowani
Postów: 208
Pomógł: 3
Dołączył: 13.07.2009
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


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?

Ten post edytował d0m1n1k_ 21.06.2015, 23:49:05
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 9)
mmmmmmm
post
Post #2





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


LOAD + help
Go to the top of the page
+Quote Post
tomxx
post
Post #3





Grupa: Zarejestrowani
Postów: 172
Pomógł: 27
Dołączył: 5.10.2013

Ostrzeżenie: (0%)
-----


Cytat
(IMG:style_emoticons/default/facepalmxd.gif)
Go to the top of the page
+Quote Post
Tuminure
post
Post #4





Grupa: Zarejestrowani
Postów: 178
Pomógł: 49
Dołączył: 16.04.2012
Skąd: Bytom

Ostrzeżenie: (0%)
-----


// 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.

Ten post edytował Tuminure 22.06.2015, 09:12:48
Go to the top of the page
+Quote Post
d0m1n1k_
post
Post #5





Grupa: Zarejestrowani
Postów: 208
Pomógł: 3
Dołączył: 13.07.2009
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


Cytat(mmmmmmm @ 22.06.2015, 07:07:23 ) *
LOAD + help


Może jakieś rozwinięcie tematu?

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


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 :-)
Go to the top of the page
+Quote Post
memory
post
Post #6





Grupa: Zarejestrowani
Postów: 616
Pomógł: 84
Dołączył: 29.11.2006
Skąd: bełchatów

Ostrzeżenie: (0%)
-----


Cytat(d0m1n1k_ @ 22.06.2015, 11:09:19 ) *
Może jakieś rozwinięcie tematu?

google bulk insert mysql

Ten post edytował memory 22.06.2015, 10:15:05
Go to the top of the page
+Quote Post
mmmmmmm
post
Post #7





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


http://dev.mysql.com/doc/refman/5.0/en/load-data.html
Go to the top of the page
+Quote Post
d0m1n1k_
post
Post #8





Grupa: Zarejestrowani
Postów: 208
Pomógł: 3
Dołączył: 13.07.2009
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


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ę...
Go to the top of the page
+Quote Post
prz3kus
post
Post #9





Grupa: Zarejestrowani
Postów: 260
Pomógł: 30
Dołączył: 22.01.2007

Ostrzeżenie: (0%)
-----


Dziwne to troche, a co tutaj jest wąskim gardłem prcek(mieli teraz na 100%)?
Go to the top of the page
+Quote Post
d0m1n1k_
post
Post #10





Grupa: Zarejestrowani
Postów: 208
Pomógł: 3
Dołączył: 13.07.2009
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


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?

Ten post edytował d0m1n1k_ 25.06.2015, 19:26:22
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 17:02