Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Optymalizacja zapytania SQL
Forum PHP.pl > Forum > Bazy danych > MySQL
neo1986kk
Witam mam 3 tabele, z których potrzebuję wyciągnąć dane

Produkty - z niej potrzebuję ID produktu (w bazie 6000 rekordów)
Dokumenty - dokumenty do produktów - potrzebuję status dokumentu ( w bazie ok 5000 rekordów)
Zamówienia - tutaj też potrzebuje tylko ID zamówienia jeśli istnieje do danego produktu ( w bazie około 15 000 rekordów)

  1. SELECT produkty.id, dokumenty.STATUS, zamowienia.id FROM produkty
  2. LEFT JOIN dokumenty ON dokumenty.product=produkty.id
  3. LEFT JOIN zamowienia z ON produkty.id=zamowienia.product
  4. WHERE (zamowienia.id=NULL OR dokumenty.STATUS!='ACCEPTED') GROUP BY produkty.id


Pokrótce: Wyciągam tylko te produkty, które nie mają zamówienia lub dokument nie jest zaakceptowany
Zapytanie działa w miarę poprawnie, jest to lekkich poprawek bo dokumentów moze być więcej niż jeden i trzeba sprawdzić czy ostatni jest zaakceptowany, ale ważniejszym problemem jest to, że
takie zapytanie SQL robi w okolo 2 minuty. Macie jakieś pomysły jak to zoptymalizować? Pozdrawiam.
nospor
  1. SELECT produkty.id, dokumenty.STATUS, zamowienia.id FROM produkty
  2. LEFT JOIN dokumenty ON (dokumenty.product=produkty.id AND dokumenty.STATUS != 'ACCEPTED')
  3. LEFT JOIN zamowienia z ON produkty.id=zamowienia.product
  4. WHERE (zamowienia.id IS NULL OR dokumenty.product IS NOT NULL) GROUP BY produkty.id

Dodatkowo wypadaloby zalozyc indeksy na pola laczace oraz szukane
neo1986kk
To może zadam dodatkowe pytanie, na id oczywiście mam primary, ale na pola status nie mam ideksu, to myślisz żeby lepiej założyć indeks na pole status w dokumentach (korzystam z tej tabeli w wielu różnych miejscach programu) , czy lepiej stworzyć nowy widok i zapytanie kierować do widoku ?
nospor
No jesli wyszukujesz po STATUS to raczej byloby milo miec na to pole index.

Widoki sa ble, szczegolnie te w mysql
neo1986kk
Troche sie poprawiło ale 36 sekund to przynajmniej o jakies 30 za długo, jeszcze założę indeksy i zobacze, jak nie bedzie poprawy to chyba mi zostanie obrobienie wszystkiego w php dodam tylko ze kiedy zapytania te są osobno to wszystko ładuje w przeciągu milisekund
nospor
36 sekund to pare razy szybciej niz 120 sekund wink.gif

Zawsze mozesz uzyc EXPLAIN i sprawdzic co dokladnie kuleje.

Jesli i to nie pomoze to warto by najpierw joinowac ZAMOWIENIA potem DOKUMENTY, ale DOKUMENTY po produkcie z zamowien. Unikniesz mnozenia rekordow
neo1986kk
  1. SELECT produkty.id, zamowienia.id FROM produkty
  2. LEFT JOIN zamowienia ON produkty.id=zamowienia.product
  3. WHERE (zamowienia.id IS NULL ) GROUP BY produkty.id


samo to 8 sec



  1. SELECT produkty.id, dokumenty.STATUS FROM produkty
  2. LEFT JOIN dokumenty ON (dokumenty.product=produkty.id AND dokumenty.STATUS !='ACCEPTED')
  3. WHERE (dokumenty.product IS NOT NULL ) GROUP BY produkty.id
  4.  


to 0.047 sec


  1. SELECT produkty.id, dokumenty.STATUS, zamowienia.id FROM produkty
  2. LEFT JOIN zamowienia ON produkty.id=zamowienia.product
  3. LEFT JOIN dokumenty ON (dokumenty.product=zamowienia.product AND dokumenty.STATUS !=18)
  4. WHERE (zamowienia.id IS NULL OR dokumenty.product IS NOT NULL ) GROUP BY produkty.id
  5.  


ale to już bez mnożenia 39 sec

ropson jak zwykle pomocny, od razu powinienem dodać indeksy,:

  1. SELECT produkty.id, dokumenty.STATUS, zamowienia.id FROM produkty
  2. LEFT JOIN zamowienia ON produkty.id=zamowienia.product
  3. LEFT JOIN dokumenty ON (dokumenty.product=zamowienia.product AND dokumenty.STATUS !=18)
  4. WHERE (zamowienia.id IS NULL OR dokumenty.product IS NOT NULL ) GROUP BY produkty.id
  5.  


0,125 sec
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.