Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Optymalizacja kodu
boro11
post 31.10.2013, 20:07:00
Post #1





Grupa: Zarejestrowani
Postów: 283
Pomógł: 11
Dołączył: 9.07.2010
Skąd: Warszawa

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


Witam!
Mam kod, który działa tak jak miał działać - tj. wykonuje wszystkie czynności jakie ma robić. Niestety obciąża mi serwer dosyć znacznie i spowalnia strony. Z indeksu przeniosłem go do jednej z podstron i trochę się poprawiło ale ta podstrona teraz działa wolno.

Oto kod:

  1. $sites = array();
  2. $limits = array();
  3. $count = array();
  4. $zap=array(1 => 'SELECT',2 => 'nazwa, limits',3 => 'FROM',4 => 'test_site');
  5. $query = $db->zap($zap);
  6.  
  7. while ($row = mysql_fetch_array($query))
  8. {
  9. $sites [$row['nazwa']] = $row['nazwa'];
  10. $limits [$row['nazwa']] = $row['limits'];
  11. $count [$row['nazwa']] = 0;
  12. }
  13.  
  14. $zap2=array(1 => 'SELECT',2 => 'site',3 => 'FROM',4 => 'test_sites',5 => 'WHERE ((status = "Approved") OR (status = "Pending"))');
  15. $quer = $db->zap($zap2);
  16. while ($row2 = mysql_fetch_array($quer))
  17. {
  18. if (in_array($row2['site'],$sites)) $count[$row2['site']]++;
  19.  
  20. if (($count[$row2['site']] > $limits[$row2['site']]) && ($limits[$row2['site']] != '~') && ($limits[$row2['site']]!='') && ($limits[$row2['site']]!='0'))
  21. {
  22. $zap3=array(1 => 'UPDATE',2 => 'test_site',3 => 'SET',4 => 'status="LIMITED"',5 => 'WHERE ((nazwa="'.$row2['site'].'") AND (status<>"SCAM"))');
  23. $db->zap($zap3);
  24. }
  25. }
  26.  
  27. $zap=array(1 => 'SELECT',2 => 'nazwa, limits',3 => 'FROM',4 => 'test_site');
  28. $query2 = $db->zap($zap);
  29. while ($row2 = mysql_fetch_array($query2))
  30. {
  31. if (isset($count[$row2['nazwa']])) $put = $count[$row2['nazwa']].'/'.$row2['limits'];
  32. else $put = '0/'.$row2['limits'];
  33. $zap=array(1 => 'UPDATE',2 => 'test_site',3 => 'SET',4 => 'refkow = "'.$put.'"',5 => 'WHERE nazwa="'.$row2['nazwa'].'"');
  34. $db->zap($zap);
  35. }


Dałoby się to jakoś zoptymalizować lub zrobić żeby robiło się np. raz na 10 minut, a nie z każdym wczytaniem strony?
Go to the top of the page
+Quote Post
SmokAnalog
post 31.10.2013, 20:11:32
Post #2





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

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


Co ten kod robi dokładnie? Nie jest na tyle czytelny, żeby chciało mi się go analizować.

Jeśli chodzi o optymalizację, to upewnij się, że pole `status` ma typ ENUM (a nie VARCHAR) i że masz indeks na polu `nazwa`. Domyślam się, że masz dużo rekordów w tej tabeli.
Go to the top of the page
+Quote Post
boro11
post 31.10.2013, 22:58:32
Post #3





Grupa: Zarejestrowani
Postów: 283
Pomógł: 11
Dołączył: 9.07.2010
Skąd: Warszawa

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


W tabeli test_sites jest obecnie 24000 rekordów (liczba ta rośnie dosyć szybko) - zmieniłem już na enum dziękuję za radę.
W tabeli test_site jest 1400 rekordów - indeksu nie mogę dodać bo mam pole ID, które ma autoinkrementacje i mi wywala błąd

Kod zarządza kategoriami stron dodanych do mojej strony. Sprawdza czy został zapełniony limit użytkowników którzy się zapisali

stąd:

  1. $put = $count[$row2['nazwa']].'/'.$row2['limits'];


nazwa to ilość zapisanych / limits to liczba określona przez nas

Jeśli liczby się wyrównają to strona jest przenoszona do innej kategorii:

  1. $zap=array(1 => 'SELECT',2 => 'nazwa, limits',3 => 'FROM',4 => 'test_site');
  2. $query2 = $db->zap($zap);
  3. while ($row2 = mysql_fetch_array($query2))
  4. {
  5. if (isset($count[$row2['nazwa']])) $put = $count[$row2['nazwa']].'/'.$row2['limits'];
  6. else $put = '0/'.$row2['limits'];
  7. $zap=array(1 => 'UPDATE',2 => 'test_site',3 => 'SET',4 => 'refkow = "'.$put.'"',5 => 'WHERE nazwa="'.$row2['nazwa'].'"');
  8. $db->zap($zap);
  9. }


Ten post edytował boro11 31.10.2013, 23:02:16
Go to the top of the page
+Quote Post
SmokAnalog
post 31.10.2013, 23:02:05
Post #4





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

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


Chodzi o indeks, a nie klucz podstawowy. Indeksy znacznie przyśpieszają wyszukiwanie po danym polu. ZNACZNIE! smile.gif
Go to the top of the page
+Quote Post
boro11
post 31.10.2013, 23:03:53
Post #5





Grupa: Zarejestrowani
Postów: 283
Pomógł: 11
Dołączył: 9.07.2010
Skąd: Warszawa

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


Okej ustawiłem indeks i rzeczywiście jest już szybciej o całe 4 sekundy, ale nadal trwa to długo bo ~3 sekund, nawet trochę więcej.

Opisałe kod w poście wyżej smile.gif

Edit: Czy dodanie tego indeksu do pola status pomoże?

Ten post edytował boro11 1.11.2013, 02:24:16
Go to the top of the page
+Quote Post
epg.kojak
post 5.11.2013, 09:51:02
Post #6





Grupa: Zarejestrowani
Postów: 6
Pomógł: 1
Dołączył: 5.11.2013
Skąd: Warszawa

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


Jeśli nie jest dla ciebie problemem, żeby ta tablica była generowana raz na 10 minut, to zrób skrypt, który wygeneruje ci taką tablicę i zapisze w pliku i ustaw w CRONie żeby skrypt był uruchamiany co 10 minut. Nie będziesz użytkownika obciążał skomplikowanymi algorytmami.
Go to the top of the page
+Quote Post
Olbrych
post 5.11.2013, 15:48:03
Post #7





Grupa: Zarejestrowani
Postów: 10
Pomógł: 2
Dołączył: 1.02.2010

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


Robisz kilka pętli i w nich zapytania. Jeżeli masz bardzo dużo rekordów to robisz masakrycznie dużo updatów. Musisz to przepisać w sql i robić update za jednym zamachem wszystkiego bo inaczej nie ma szans na szybkie działanie.
Zrób echo wszystkich zapytań to będzie lepiej widać jak można to napisać.
Go to the top of the page
+Quote Post
zegarek84
post 5.11.2013, 20:36:29
Post #8





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

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


skoro update robisz w pętli i jest on zależny od zewnętrznego zapytania to wystarczyło by, gdybyś ten update robił w jednej transakcji na całą pętlę, poczytaj o tym...

oprócz tego pierwszą pętlę z UPDATE możesz załatwić w jednym zapytaniu gdyż zmienia się tylko warunek WHERE a reszta jest statyczna
SQL IN Operator
drugi update to już raczej trzeba zacząć transakcję przed pętlą i zakończyć za pętlą...

choć jeszcze to Ci się nie przyda, ale np. ja problem z aktualizacją wielu danych z plików XML (sporych więc parsowałem te pliki nie przez DOM a SAX) gdzie czasami trzeba było dodać nowe rekordy rozwiązałem w ten sposób, iż tworzyłem tabelę tymczasową identyczną i w transakcji robiłem insert, po czym zapytanie gdzie id się powtarzało (nie mam tam autoinkrementacji - można to dać też na inne unikalne rekordy) robiłem jednym zapytaniem UPDATE from SELECT , kolejnym insert from select, a kolejnym usuwałem tabelę tymczasową...


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

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: 14.08.2025 - 13:43