Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [mysql] optymalne zapytanie sql
Forum PHP.pl > Forum > Przedszkole
yalus
witam

w bazie mam kilka tabel z ktorych chcialbym wyciagnac dane przy uzyciu jednego (ponizszego) zapytania:


  1. SELECT * FROM tabela1, tabela2, tabela3 WHERE tabela1.STATUS='green' AND tabela1.id=tabela2.id AND tabela2.id=tabela3.id ORDER BY tabela1.STATUS DESC LIMIT 0, 200


struktory tabel sa nastepujace:

tabela1
id imie nazwisko status

tabela2
id kol1 kol2 kol3 ... kol25

tabela3
id kol1 kol2 kol3 ... kol15


w tabeli1 sa 4 kolumny i okolo 45tys rekordow
w tabeli2 jest 25 kolumn i okolo 60tys rekordow
w tabeli3 jest 15 kolumn i okolo 20tys rekordow


powyzsze zapytanie dziala poprawnie ale czasami sie 'zawiesza' tzn trwa dluzej niz 30sek i dostaje komunikat o przekroczonym czasie na wykonanie skryptu

pytanie moje brzmi:

czy zapytanie to jest skonstruowane w optymalny sposob?
jaka jest roznica pomiedzy tak skonstruowanym zapytaniem a zapytaniem przy uzyciu JOIN?
czy duza liczba rekordow moze miec wplyw na czas nawet jak ograniczam do wyswietlenia tylko dwustu rekordow?
i ostatnie jak moglbym zmniejszyc czas dla takiego zapytania - czy wogole da sie cos zrobic?
Kihol
Po pierwsze sprawdź, czy to na pewno samo zapytanie trwa tyle czasu - bo robiąc LIMIT na 200 rekordów nie interesuje bazy, że jest ich tak na prawdę 20000.
Samego złączenia nie da się napisać bardziej optymalnie - bo JOIN będzie na pewno wolniejszy.
nevt
a ja bym jednak użył JOIN + PODZAPYTANIE:
  1. SELECT * FROM (SELECT * FROM tabela1 WHERE tabela1.STATUS='green' LIMIT 200 ) AS tmp LEFT JOIN tabela2 USING (id) LEFT JOIN tabela3 USING (id);

powody?
1. twoja konstrukcja najpierw robi sortowanie i złączenia na wszystkich rekordach wszystkich tabel, a dopiero na końcu wynik jest przycinany przez LIMIT
2. wyrażenie (ORDER BY tabela1.status DESC) nie ma sensu jeśli wczesniej masz warunek (WHERE tabela1.status = 'green') - wszystkie pola status mają tą samą wartość i nie ma czego sortować...
3. w mojej wersji NAJPIERW wykona się podapytanie "wyłuskujące" z tabela1 te właściwych 200 rekordów, a dopiero później nastąpi złączenie (już nie wszystkich danych tylko tych 200 rekordów)

nie mogę tego sprawdzić na 100% bo nie mam bazy z takimi ilościami danych - ale wrzuć to do swojej i sprawdź, jeżeli nie walnąłem jakiegoś byka - powinno być wydajniej. powodzenia

EDIT: no i sprawa pozornie oczywista - zakładam, że masz pozakładane indeksy na polach: status i id (we wszystkich tabelach)?
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.