Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php/mysql] Przeglądarki wieszają się przy zapytaniu SQL
Forum PHP.pl > Forum > Przedszkole
Jarod
Mam zoptymalizowane zapytanie sql (przynajmniej tak mi się wydaje, indeksy pozakładane), które pobiera z bazy pewne dane na konkretny dzień (bieżąca data). Dane wyciągane są z dwóch tabel. Wszystko ładnie śmiga, dopóki nie próbuję pobierać danych z pewnego zakresu dat. Np.
  1. SELECT (...) FROM (...) WHERE DATA BETWEEN '2008-01-01' AND '2008-02-01' AND (...)

Takie zapytanie zwraca mi około 1500wierszy. Następnie za pomocą foreach() wyświetlam je na stronie. Wystarczy zakres miesiąca w datach aby przeglądarka (FF, Opera i IE) zawieszała się na czas generowania strony. Po prostu nie reaguje na polecenia. W tym samym czasie obciążenie procesora wzrasta do 100% i utrzymuje się jeszcze kilkanaście sekund po wykonaniu zapytania!!! Firefox pokazuje mi że strona ładowana jest około 56sekund. Aplikacja intranetowa, nie ma znaczenia czy testuje lokalnie czy na szybkim serwerze Hp dwurdzeniowym z 2Gb pamięci. Dodatkowo Firefox po zakończeniu generowania strony bardzo wolno działa czasami przestaje (trzeba ubijać proces). Najciekawsze jest to, że samo zapytanie generuje się:

- w konsoli mysql ~0,5sekundy
- aplikacja podaje, że cały skrypt php wykonał się w ~0,7sekund

Sprawdzałem WinCacheGrind i nie ma żadnego "wąskiego gardła". To, że firefox muli jeśli na stronie jest dużo danych to wiedziałem. Ale dlaczego wszystkie przeglądarki tak długo generują stronę i nie reagują? Spotkaliście się z czymś takim?
qrees
Cytat(Jarod @ 30.03.2008, 14:36:08 ) *
Mam zoptymalizowane zapytanie sql (przynajmniej tak mi się wydaje, indeksy pozakładane), które pobiera z bazy pewne dane na konkretny dzień (bieżąca data). Dane wyciągane są z dwóch tabel. Wszystko ładnie śmiga, dopóki nie próbuję pobierać danych z pewnego zakresu dat. Np.
  1. SELECT (...) FROM (...) WHERE DATA BETWEEN '2008-01-01' AND '2008-02-01' AND (...)

Takie zapytanie zwraca mi około 1500wierszy. Następnie za pomocą foreach() wyświetlam je na stronie. Wystarczy zakres miesiąca w datach aby przeglądarka (FF, Opera i IE) zawieszała się na czas generowania strony. Po prostu nie reaguje na polecenia. W tym samym czasie obciążenie procesora wzrasta do 100% i utrzymuje się jeszcze kilkanaście sekund po wykonaniu zapytania!!! Firefox pokazuje mi że strona ładowana jest około 56sekund. Aplikacja intranetowa, nie ma znaczenia czy testuje lokalnie czy na szybkim serwerze Hp dwurdzeniowym z 2Gb pamięci. Dodatkowo Firefox po zakończeniu generowania strony bardzo wolno działa czasami przestaje (trzeba ubijać proces). Najciekawsze jest to, że samo zapytanie generuje się:

- w konsoli mysql ~0,5sekundy
- aplikacja podaje, że cały skrypt php wykonał się w ~0,7sekund

Sprawdzałem WinCacheGrind i nie ma żadnego "wąskiego gardła". To, że firefox muli jeśli na stronie jest dużo danych to wiedziałem. Ale dlaczego wszystkie przeglądarki tak długo generują stronę i nie reagują? Spotkaliście się z czymś takim?

SQL nie ma nic wspólnego z przeglądarką i jej szybkim działaniem. To jest kwestia wielkości wygenerowanej strony. Jeżeli wygenerujesz tak dużą stronę bez zapytania SQL to też będzie działać wolno. Dlatego też nie ma znaczenia gdzie aplikacja się znajduje. I dlatego też samo zapytanie, czy też skrypt php wykonuje się poniżej sekundy. To nie jest kwestia tylko firefoxa, tylko wielkości strony. Jakiejbyś przeglądarki nie wziął to zawsze będzie problem przy olbrzymich stronach. Może trzeba zainwestować w więcej ramu? Bez samej strony niewiele ci tu pomogę...
Jarod
Cytat(qrees @ 30.03.2008, 14:25:48 ) *
SQL nie ma nic wspólnego z przeglądarką i jej szybkim działaniem. To jest kwestia wielkości wygenerowanej strony. Jeżeli wygenerujesz tak dużą stronę bez zapytania SQL to też będzie działać wolno. Dlatego też nie ma znaczenia gdzie aplikacja się znajduje. I dlatego też samo zapytanie, czy też skrypt php wykonuje się poniżej sekundy. To nie jest kwestia tylko firefoxa, tylko wielkości strony. Jakiejbyś przeglądarki nie wziął to zawsze będzie problem przy olbrzymich stronach. Może trzeba zainwestować w więcej ramu? Bez samej strony niewiele ci tu pomogę...


Też tak myślałem ponieważ testy pokazują, że od strony php wszystko szybko się wykonuje, natomiast wiesza się podczas renderignu po stronie klienta.
Na początku myślałem, że to sql tak wiesza ale przecież to nie możliwe.
Więcej ramu? Na komputerze, który testuje jest jakiś celeron i 1Gb ram, na lapku Core2Due i 1Gb ram. Uważasz, że to mało? Chyba nie. Zastanawia mnie także 100% obciążanie procka podczas generowania strony.

Niestety aplikacja jest jest firmowa i nie mogę jej udostępniać osobom z poza firmy. Wbrew pozorom najlepiej radzi sobie IE - szybciej się odwiesza. Zastanawiam się czy to może być kwesta dużego cssa. Jeszcze spróbuje pobrać z bazy te rekordy i wygenerować bez obróbki css - czysty prost test i zobaczę jak się zachowują przeglądarki.

BTW: JAk jest z tym cssem - przeglądarki pobierają go tylko raz i trzymają w cache? A jeśli w stronie wstawiam w meta nagłówek wymuszający przeładowanie - to także dotyczy cache?

pzdr
dr_bonzo
Masz po prostu wieeeelka strone (widziales zeby allegro mialo 1500 produktow / strone?) i moze ona przymulic kazdy sprzet.
qrees
Cytat(Jarod @ 30.03.2008, 20:43:58 ) *
Też tak myślałem ponieważ testy pokazują, że od strony php wszystko szybko się wykonuje, natomiast wiesza się podczas renderignu po stronie klienta.
Na początku myślałem, że to sql tak wiesza ale przecież to nie możliwe.
Więcej ramu? Na komputerze, który testuje jest jakiś celeron i 1Gb ram, na lapku Core2Due i 1Gb ram. Uważasz, że to mało? Chyba nie. Zastanawia mnie także 100% obciążanie procka podczas generowania strony.

1GB ma taką stronę... tak, uważam, że to mało, ale może lepiej zastanowić się nad optymalizacją strony.
Cytat(Jarod @ 30.03.2008, 20:43:58 ) *
Niestety aplikacja jest jest firmowa i nie mogę jej udostępniać osobom z poza firmy. Wbrew pozorom najlepiej radzi sobie IE - szybciej się odwiesza. Zastanawiam się czy to może być kwesta dużego cssa. Jeszcze spróbuje pobrać z bazy te rekordy i wygenerować bez obróbki css - czysty prost test i zobaczę jak się zachowują przeglądarki.

BTW: JAk jest z tym cssem - przeglądarki pobierają go tylko raz i trzymają w cache? A jeśli w stronie wstawiam w meta nagłówek wymuszający przeładowanie - to także dotyczy cache?

pzdr

to czy css jest pobierany raz czy nie zależy w dużej mierze od konfiguracji serwera i jakie nagłówki wysyła. Dobrze skonfigurowany serwer będzie wysyłał css tylko gdy się zmieni (podobnie jak inne pliki).

Co do nagłówka meta, to pewnie chodzi ci o css, a nie o cache, bo przeładowanie strony przez pobranie jej z cachu jest trochę bez sensu... A co do css, to pewnie jest tak jak napisałem wyżej.
Jarod
Cytat(qrees @ 30.03.2008, 19:00:09 ) *
1GB ma taką stronę... tak, uważam, że to mało, ale może lepiej zastanowić się nad optymalizacją strony.

Ale co tu optymalizować? Jedyne co mógłbym zrobić to porcjować dane i tyle.

Dla ciekawostki (3877 wiersze):
- wyniki z czterech miesięcy w konsoli: 0.97s
- wyniki z czterech miesięcy w przeglądarce (sam foreach bez znaczników i css'a) - wykonywanie skryptu: 8.20s, generowanie strony: 8.54s
- wyniki z czterech miesięcy w przeglądarce (pełna obróbka czyli znaczniki + css) - wykonywanie skryptu: ? ff zawiesił się, generowanie strony: co najmniej 200s

Cytat(qrees @ 30.03.2008, 19:00:09 ) *
to czy css jest pobierany raz czy nie zależy w dużej mierze od konfiguracji serwera i jakie nagłówki wysyła. Dobrze skonfigurowany serwer będzie wysyłał css tylko gdy się zmieni (podobnie jak inne pliki).

Co do nagłówka meta, to pewnie chodzi ci o css, a nie o cache, bo przeładowanie strony przez pobranie jej z cachu jest trochę bez sensu... A co do css, to pewnie jest tak jak napisałem wyżej.

Możesz napisać coś więcej o tej konfiguracji?



E D I T:
=====


Zrobiłem jeszcze jeden mały test aby wykluczyć to, że b. duży CSS może tak wpływać na zachowania przeglądarek.
Dane z jednego miesiąca (około 1370wierszy) obrabiany w następujący sposób:
  1. <?php
  2. foreach($aVs As $aV)
  3. {
  4. echo '<div>';
  5. echo '<p><a id="keeper' . $this->iKeeper . '" href="' . Config::$SystemPath . 'main/pl/SomeAction/date/' . $this->iYear . '-' . $this->iMonth . '-' . $this->iDay . '/id/' . $aV['a'] . '/' . ($this->iKeeper - 1) . '/#keeper' . ($this->iKeeper - 1) . '">' . $aV['a'] . '</a></p>';
  6. echo '<p>' . $aV['b'] . '</p>';
  7. echo '<p>' . $aV['c'] . '</p>';
  8. echo '<p>' . $aV['d'] . '</p>';
  9. echo '<p>' . $aV['e'] . '</p>';
  10. echo '<p>' . $aV['e'] . '</p>';
  11. echo '<p>' . $aV['f'] . '</p>';
  12. echo '<p>' . $aV['g'] . '</p>';
  13. echo '<p>' . $aV['h'] . '</p>';
  14. echo '<p>' . $aV['i'] . '</p>';
  15. echo '<p>' . $aV['j'] . '</p>';
  16. if ($aVoyage['k'])
  17. {
  18. echo '<div><input type="checkbox" name="" value="" checked="checked" disabled="disabled" /></div>';
  19. }
  20. else
  21. {
  22. echo '<div><input type="checkbox" name="" value="" disabled="disabled" /></div>';
  23. }
  24. echo '<p>' . $aV['l'] . '</p>';
  25. echo '</div>';
  26.  
  27. $this->iKeeper++;
  28. }
  29. ?>

Skrypt wykonuje się w: 1.0003s
Strona generowana przez przeglądarkę w: 2.672s


Jeśli da każdego znacznika dodam style float: left; i dodatkowo w pierwszym clear: both; czyli mniej więcej coś takiego:
  1. <?php
  2. foreach($aVs As $aV)
  3. {
  4. echo '<div>';
  5. echo '<p style="float: left; clear: both;"><a id="keeper' . $this->iKeeper . '" href="' . Config::$SystemPath . 'main/pl/SomeAction/date/' . $this->iYear . '-' . $this->iMonth . '-' . $this->iDay . '/id/' . $aV['a'] . '/' . ($this->iKeeper - 1) . '/#keeper' . ($this->iKeeper - 1) . '">' . $aV['a'] . '</a></p>';
  6. echo '<p style="float: left;">' . $aV['b'] . '</p>';
  7. echo '<p style="float: left;">' . $aV['c'] . '</p>';
  8. (...)
  9. ?>

Skrypt wykonuje się w: 1.03169s
Strona generowana przez przeglądarkę w: 108.76s
Obciążenie procka: 100%


Czyli wychodzi na to, że przeglądarki przy dużej ilości danych i cssie dławią się.
Chrom
ja bym zaczął od zmiany formatu daty
Jarod
Cytat(Chrom @ 31.03.2008, 05:02:11 ) *
ja bym zaczął od zmiany formatu daty

A niby po co? snitch.gif
qrees
Proponuje zainstalować Firebug'a i YSlow. YSlow bada stronę pod kątem prędkości ładowania, ilości żądań HTTP i podaje sugestie jak poprawić działanie strony.
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.