Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Strona ładuje się koszmarnie długo (nawet 45 sekund)
Forum PHP.pl > Forum > PHP
L_Devil
Jedna, jedyna podstrona mojego serwisu, której przeznaczeniem jest generowanie prostego pliku html na potrzeby AJAXa, wykonuje się 45 sekund (tyle mija od wybrania jej do otworzenia jej). Skrypt nie zawiera nic specjalnego (od, kilka zapytań do bazy danych, układanie graficzne wyników). Wszystkie pozostałe strony serwisu (nawet znacznie bardziej skomplikowane) otwierają się w ciągu 3 - 5 sekundy. Zirytowany postanowiłem testować microtimem czas generowania strony, ale pod sam jej koniec (tuż nad die'm) czas wynosił 0.4 - 0.9 sekundy. Widać jednak spory spadek wydajności (0.2 sekundy) w linijce dotyczącej zapytania:
  1. SELECT u.value AS name, shout.text AS text FROM shoutbox AS shout, users AS u WHERE shout.location='main' AND u.owner=shout.owner AND u.name='name' ORDER BY shout.id DESC LIMIT 10;
Baza danych chodzi na InnoDB.

A, jeszcze jedno. Dość często się zdarza że w tej linijce następuje ujemny przyrost czasu (!) (tzn linijkę wyżej mamy czas microtime: 0.7, a po tej linijce mamy: 0.5)

Mam nadzieję, że ktoś spotkał się już z czymś podobnym, bo to mi żyć nie daje...
Riklaunim
użyj xdebug to się dowiesz gdzie jest problem. 0.2 na zapytanie to nie problem przy 45 sekundach wykonywania skryptu.
L_Devil
Moja nieuwaga:

Start pliku: 0.51586200 1182753779
krok 1: 0.63114900 1182753779
- Zapytanie -
krok 2: 0.85077600 1182753795
Finish: 0.87077600 1182753795

Czyli jednak to to zapytanie. Co w nim może być nie tak, że się wykonuje prawie 20 sekund? (nie wliczając czasu na pobieranie wyników)
Luke_Star
a ta baza jest na komputerze lokalnym? Jak tak to jakie jest obciazenie kompa (pamiec, procesor) oraz jaka tam masz konfiguracje smile.gif. Czasami poprostu jak sie zamuli za bardzo kompa to te procesy baz danych sa woooolne w cholere.
em_pl
a ile GB ma ta baza? biggrin.gif Ogólnie łączenie jest średnio wydajnym rozwiązaniem zazwyczaj. Przy wielkich bazach bez indeksowania tak się może dziać (znam to z autopsji tongue.gif)
L_Devil
Baza jest na serwerze home.pl

Cała baza ma 21 mb

Układ tabel:
Kod
users:

+--+------+------+---------+
|id|owner | name |  value  |
+--+------+------+---------+
|1 |   1  | name | Piotr   |
|2 |   1  | param| value   |
|3 |   2  | name | Maciek  |
|4 |   2  | param| value2  |
|5 |   3  | name | Olga    |
|6 |   3  | param| value3  |
+--+------+------+---------+

shoutbox:

+--+----------+------+--------------+
|id| location |owner |     text     |
+--+----------+------+--------------+
|1 |   main   |  1   | Witaj, Maciek|
|2 |   main   |  2   | Witaj, Piotr |
|3 |   main   |  1   | Gdzie Olga?  |
|4 |   main   |  3   | Nie ma mnie  |
|5 |   main   |  1   | Aha          |
|6 |   other  |  1   | Test test    |
+--+----------+------+--------------+
UDAT
Jeśli nie masz indeksów, to je załóż.

Następnie zmień zapytanie na normalnego JOIN'a ( o ile pamiętam przy czymś takim co ty pokazałeś nie są używane indeksy i wogóle jest to wolniejsze od zwykłego JOIN'a ).

EDIT:
Pomyliłem się.
L_Devil
Cytat(UDAT @ 25.06.2007, 13:28:25 ) *
Jeśli nie masz indeksów, to je załóż.
Pola id są typu PRIMARY(`id`) auto_increment... więc indeksy generalnie są smile.gif
Cytat(UDAT @ 25.06.2007, 13:28:25 ) *
Następnie zmień zapytanie na normalnego JOIN'a ( o ile pamiętam przy czymś takim co ty pokazałeś nie są używane indeksy i wogóle jest to wolniejsze od zwykłego JOIN'a ).
EDIT:
Pomyliłem się.
Z tego co wiem nie ma znaczenia czy napiszę z widocznym JOINem, czy z ukrytym JOINem... a w każdym razie nie powinno robić to różnicy:

phpmyadmin -> Pokaż rekordy 0 - 9 (10 wszystkich, Wykonanie zapytania trwało 16.8165 sekund(y))

Licho ciężkie... tym gorzej że ja kompletnie nie mam pomysłu dlaczego tak. Baza danych na InnoDB, tabela users ma 13 836 rekordów (3,5 mb), zaś tabela shoutbox ma 2 731 rekordów (1,5 mb)


Edit - zrobiłem kopię bazy danych w MySQL 4.1 - problemu nie ma. Czyli sprawa występuje tylko w MySQL 5... Może ta wskazówka komuś pomoże na to wpaść? Niestety główną bazę muszę trzymać w mysqlu 5...
cicik
sprawdź komendą EXPLAIN jaki jest plan wykonania zapytania
L_Devil
Zdaniem phpmyadmina:

Kod
id   select_type  table  type  possible_keys  key    key_len   ref   rows    Extra
1    SIMPLE       shout  ALL   NULL           NULL   NULL      NULL  2791    Using where; Using temporary; Using filesort
1    SIMPLE       u      ALL   NULL           NULL   NULL      NULL  14345   Using where
cicik
No twoje zapytanie nie używa indeksów. To nie może być szybkie. I jeszcze sortowanie... I to wszystko z tabelą tymczasową. Ojojoj. Tak się zabija bazę.
Załóż indeks, na pole po którym łączysz tabele. Powinno pomóc.
L_Devil
Sortuję według indeksów, ale nie mogę założyć indeksu na pole owner, bo nie jest unikalne... Chyba że się mylę.

Tak czy inaczej dochodzimy już do czegoś smile.gif

A tabeli tymczasowej jawnie nie używam - więc skąd się bierze?
cicik
A kto powiedział, że indeks można założyć tylko na polu unikalnym? Czytaj manuale.

Cytat(L_Devil @ 25.06.2007, 22:22:08 ) *
A tabeli tymczasowej jawnie nie używam - więc skąd się bierze?


Robi się sama (w tle). Powstaje ze złączenia dwóch tabel po to by móc zastosować warunki i sortowanie.
Czytaj manuale.
L_Devil
oh, god, takie to proste... indeks założony i zapytanie wykonuje się 0.0005 sekundy.

Wielkie dzięki Cicik, wygląda na to że muszę się jeszcze sporo dokształcić z mySQLa smile.gif
cicik
Cytat(L_Devil @ 26.06.2007, 12:15:57 ) *
wygląda na to że muszę się jeszcze sporo dokształcić z mySQLa smile.gif


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