Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wolne wykonywanie INSERT do MySQL-a
Forum PHP.pl > Forum > Bazy danych
MiChaSSs
Hej,
Co prawda aplikacja jest napisana w C (z wykorzystaniem MySQL API) a nie w PHP, ale problem tkwi po stronie MySQL-a stad pisze tutaj a nie na forum C/C++. Program ktory napisalem, ma wrzucac informacje z przeparsowanego pliku tekstowego do bazy danych, problem polega tylko na tym, ze tych danych jest sporo (stad wybralem C a nie PHP). Sprobowalem wrzucic dane tylko z 1 pliku co daje ~ 3487 zapytan do bazy danych i program wykonywal sie przez prawie 3 minuty! Co przy ponad 500 plikach daje wiecznosc wink.gif. No ale pomyslalem, ze moze jest to wina braku optymalizacji programu, wiec postanowilem napisac cos takiego:

  1. int i;
  2.  
  3. for(i =0; i < 3486; i++)
  4. {
  5. mysql_query(mysql_connection, "INSERT INTO `tabela` VALUES(20110608,1234.0,1234.0,1234.0,1234.0,1234)");
  6. }


gdzie tabela to:

  1. CREATE TABLE `tabela` IF NOT EXISTS
  2. (
  3. kolumna_1 DATE DEFAULT NULL,
  4. kolumna_2 FLOAT(5,2) DEFAULT NULL,
  5. kolumna_3 FLOAT(5,2) DEFAULT NULL,
  6. kolumna_4 FLOAT(5,2) DEFAULT NULL,
  7. kolumna_5 FLOAT(5,2) DEFAULT NULL,
  8. kolumna_6 FLOAT(5,2) DEFAULT NULL
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


Kod pisalem z pamieci (nie mam teraz dostepu do zrodla programu) wiec moga gdzies byc byki, ale chcialem przekazac tylko sens. Okazalo sie, ze przedstawiony wyzej kod tez wykonuje sie w granicach 3 minut ;/. Mieliscie kiedys podobna sytuacje? Dlaczego tak sie dzieje? Jak to naprawic? Dziekuje za wszelka pomoc, pozdrawiam MD
nospor
skoro rekordów jest dużo, ale widzę są one krótkie to jednym zapytaniem wkładaj np po 10 rekordów
....values (rekord1), (rekord2), (rekord10)

Wiecej info masz w dokumentacji
http://dev.mysql.com/doc/refman/5.5/en/insert.html
Będzie zdecydowanie szybciej
wookieb
Możesz również opakować grupę opreacji insert w transakcje.
thek
Możliwe, że spowalniaczem są:
a) operacje odczytu plików z dysku,
cool.gif ciągłe nawiązywanie nowych połączeń zamiast używanie jednego przez cały czas skryptu,
c) niezbyt wydajne parsowanie zawartości.

Trudno cokolwiek powiedzieć bez jakiejś faktycznej próbki kodu i tego jak wygląda obróbka plików do formy zapytań. Pamiętaj, że operacje I/O sa zawsze wąskim gardłem i to one głównie spowalniają aplikację.
MiChaSSs
@nospor && @wookieb -> sprobuje wink.gif

@thek

Ad.1 byc moze, ale malo prawdopodobne bo wszystkie pliki maja ~ 40MB (a jest ich nieco ponad 500)
Ad.2 nawiazuje tylko 1 polaczenie przez caly czas pracy programu
Ad.3 nie, bo zrobilem tak, jak to napisalem w 1 poscie zeby to sprawdzic

----------------------------------------------------------------------------------------

EDIT 2011.06.09 10:17


Zmodyfikowalem wczoraj kod i zaimplementowalem tranzakcje -- 10 000 zapytan poszlo w 1.5s, gdzie wczesniej przypominam ~3500 zapytan wrzucalo sie do bazy w 3 minuty wink.gif Dzieki! A teraz kolejne pytanie ... skoro puszczam kilka insertow na raz, w takim razie w jaki sposob moge wyznaczyc maxymalny limit zapytan w trakcie jednej tranzakcji? Przy takim kodzie jaki zaprezentowalem w pierwszym poscie (tylko z wykananiem zapytania PRZED petla "START TRANSACTION" i ZA petla "COMMIT") wczoraj i 100 000 zapytan poszlo w 14s, ale co gdy zapytanie jest bardziej udziwnione? Jak mozna to "wyliczyc"? Przypuszczam, ze ma tutaj znaczenie zmienna max_allowed_packet (w my.conf -- u mnie standardowo 16M), no ale jak wyliczyc ile zapytan da te 16M? Pozdrawiam MD
uupah5
zabierasz się za to od złej strony.
manual mysql, szukaj składni LOAD DATA LOCAL INFILE 'xxx' INTO TABLE wraz z opcjami

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.