Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL][PHP] Optymalizacja zapisu do bazy danych, zapis danych w pętli
zibideusz
post 31.08.2011, 08:36:10
Post #1





Grupa: Zarejestrowani
Postów: 21
Pomógł: 1
Dołączył: 14.05.2009

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


Witam serdecznie smile.gif

Jak zwykle piszę z problemem. Otóż mój skrypt wykonuje pętle (while) i przy każdym wykonaniu zapisuje dane do bazy. Skrypt wykonuje się do momentu przekorczenia czasu wykonywania. Chodzi po prostu o to, by pętli wykonało się jak najwięcej, nie chcę ograniczać tego do konkretnej wartości, bo w zależności od danych raz potrafi przejść 5 pętli, a innym razem 30.

No i sporo już myślałem nad tym, w jaki sposób ominąć zapisywanie danych co każdą pętlę (generuje to spore obciążenia). Pomsł mam taki, by dane przechowywać w tablicy i w odpowiednim momencie (przed zakończeniem czasu wykonywania) zapisać do bazy. Wymagałoby to porównywania czasu rozpoczęcia pierwszej pętli z obecnym i na przykład po upływie 50 sekund przerwać pętlę i zrobić zapis.

Są jeszcze jakiś inne sposoby?
Go to the top of the page
+Quote Post
phpion
post 31.08.2011, 08:49:10
Post #2





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Spróbuj zapisywać dane do pliku na dysku, a po zakończeniu ich zapisywania odpal LOAD DATA INFILE. Powinno być zdecydowanie bardziej wydajne.

Inna sprawa, to podane przez Ciebie wartości: od 5 do 30 przebiegów pętli. Przyjmując domyślny czas wykonywania skryptów (30 sekund) daje to od 1 do 6 sekund na jeden przebieg pętli. Trochę dużo... stawiam na problemy wewnątrz samej pętli. Zawsze możesz również wydłużyć czas wykonywania skryptu.
Go to the top of the page
+Quote Post
exood
post 31.08.2011, 08:56:59
Post #3





Grupa: Zarejestrowani
Postów: 86
Pomógł: 16
Dołączył: 2.12.2009
Skąd: Płock/Warszawa

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


daj w środku pętli:

jęzeli możesz zmienić limit (uwarunkowania serwera) to masz 20 sekund na każdy obieg pętli
ale to nie zmienia faktu, że coś długo trwają te operacje w petli i bardziej uważnie bym im się przyjrzał
Go to the top of the page
+Quote Post
zibideusz
post 31.08.2011, 09:01:36
Post #4





Grupa: Zarejestrowani
Postów: 21
Pomógł: 1
Dołączył: 14.05.2009

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


W pętli pobierane są dane z innych stron (curl), stąd długi czas wykonywania 1 pętli.

Zapisywanie danych do pliku w każdej pętli, a później zrzut całości do bazy zmniejszy obciążenie?
Go to the top of the page
+Quote Post
mortus
post 31.08.2011, 09:06:50
Post #5





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


W pętli generuj tylko zapytanie i np. co 10 przebiegów je wykonuj:
  1. $i = 0;
  2. $count = count($data);
  3. $sql = 'INSERT INTO `tabela` VALUES';
  4. while($i < $count) {
  5. if(($i > 0 && $i%10 == 0) || $i == $count - 1) {
  6. $sql = substr($sql, 0, -1);
  7. mysql_query($sql);
  8. $sql = 'INSERT INTO `tabela` VALUES';
  9. }
  10. $sql .= '('.$data[$i]['id'].', "'.$data[$i]['username'].'"),'; // itd.
  11. }

Choć przy dużej ilości stron pobieranych curl-em może to niewiele pomóc.

Ten post edytował mortus 31.08.2011, 09:07:23
Go to the top of the page
+Quote Post
zibideusz
post 31.08.2011, 09:17:34
Post #6





Grupa: Zarejestrowani
Postów: 21
Pomógł: 1
Dołączył: 14.05.2009

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


Każda nawet najmniejsza optymalizacja zapytań to dobry pomysł smile.gif
Wykonywanie zapytań co kilka kroków jest o tyle zła, że niektóre dane nie zostaną zapisane. Na przykład ustawię zapisywanie co 3 pętle, wykona mi 10 pętli, wtedy tracę dane z wykonania ostatniej. A tego nie chcemy smile.gif

A co myślicie o moim pomyśle, by porównywać czas i w odpowiednim momencie przerwać pętle? Połączyłbym to ze sposobem podanym przez mortusa (dziękuję za pomysł).
Go to the top of the page
+Quote Post
mortus
post 31.08.2011, 09:59:54
Post #7





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


Cytat
Wykonywanie zapytań co kilka kroków jest o tyle zła, że niektóre dane nie zostaną zapisane. Na przykład ustawię zapisywanie co 3 pętle, wykona mi 10 pętli, wtedy tracę dane z wykonania ostatniej. A tego nie chcemy smile.gif

Zauważ, że dzięki warunkowi || $i == $count - 1 zostaną zapisane wszystkie dane:
  1. if(($i > 0 && $i%10 == 0) || $i == $count - 1) {


EDIT
Choć wtedy trzeba troszkę zmodyfikować kod:
  1. $i = 1;
  2. $count = count($data);
  3. $sql = 'INSERT INTO `tabela` VALUES';
  4. while($i-1 < $count) {
  5. $sql .= '('.$data[$i-1]['id'].', "'.$data[$i-1]['username'].'"),'; // itd.
  6. if($i%10 == 0 || $i-1 == $count - 1) {
  7. $sql = substr($sql, 0, -1);
  8. mysql_query($sql);
  9. $sql = 'INSERT INTO `tabela` VALUES';
  10. }
  11. }


Co do Twojego pomysłu, to co będzie z danymi, które nie zostaną przetworzone? Wznowisz wykonywanie skryptu?

Ten post edytował mortus 31.08.2011, 10:10:42
Go to the top of the page
+Quote Post
zibideusz
post 31.08.2011, 10:20:30
Post #8





Grupa: Zarejestrowani
Postów: 21
Pomógł: 1
Dołączył: 14.05.2009

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


Tak, zostanie to wznowione.
Na przykład mam w sumie 50 zadań do wykonania w pętli. Za pierwszym razem wykona się 15, to następna pętla zaczyna się od 16.

Nie wiem czy dobrze zrozumiałem, ale w Twoim przykładzie chyba zakładasz, że z góry została założona ilość pętli i zostannie ona wykonana do końca. Mój skrypt bardzo rzadko wykonuje wszystkie zaplanowane pętle.
Go to the top of the page
+Quote Post
mortus
post 31.08.2011, 10:47:59
Post #9





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


Czyli wygląda na to, że ten CURL u Ciebie działa raz szybciej, raz wolniej i w sumie to nie wiesz, kiedy braknie czasu na dokończenie działania skryptu. To w takim razie Twoje rozwiązanie może być dobre, ale nie wiem, czy warto porównywać czas, czy może na sztywno ustalić przeładowania strony np. co 5 przebiegów pętli. Trzeba pamiętać, że od momentu, w którym porównasz czasy, do momentu w którym nastąpi przeładowanie strony też trochę czasu mija (choć może niewiele).
Nie bawiłem się jeszcze tym, ale można by było spróbować zasymulować wielowątkowość do wygenerowania zapytań/nia SQL (niestety to co znalazłem w sieci działa tylko na *nix-ach).
Go to the top of the page
+Quote Post
zibideusz
post 31.08.2011, 11:12:36
Post #10





Grupa: Zarejestrowani
Postów: 21
Pomógł: 1
Dołączył: 14.05.2009

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


Dzięki serdecznie smile.gif Trochę się pobawię z tymi czasami, może coś się uda wymodzić smile.gif
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 19.07.2025 - 05:41