Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Optymalizacja zapytania SQL z funkcja COUNT ?
Forum PHP.pl > Forum > PHP
luckyluc
Witam, mam problem z zapytaniem SQL. Stworzyłem do systemu newsow komentarze. Na stronie głównej przy każdym newsie licznik pokazuje ile jest komentarzy dla danego newsa. Komentarzy jest jak dużo, że przeliczenie tego obciąża serwer w takim stopniu, że destabilizuje jego prace. Poniżej wklejam zapytanie:


SELECT SQL_CALC_FOUND_ROWS newsy_id,newsy_data,newsy_czas,newsy_licznik,newsy_tytul,newsy_tekstskrocony,new
sy_tekstrozszerzony,newsy_foto,fotosy_file,dzialy_nazwa,COUNT(komentarze_id) licznik FROM newsy LEFT JOIN fotosy ON (fotosy_id=newsy_foto) LEFT JOIN dzialy ON (dzialy_id=newsy_dzial) LEFT JOIN komentarze ON (komentarze_news = newsy_id AND komentarze_status = '1') WHERE newsy_status='1' GROUP BY newsy_id ORDER BY newsy_data DESC, newsy_czas DESC LIMIT 0, 25


Będę wdzięczny za uwagi.
wry
mysle ze te 3 joiny w zapytaniu robia swoje, samo liczenie moglbys zorganizowac w osobnym zapytaniu wykonujac count po kolumnie na ktorej masz zalozony index (np po auto increment'owanym id) a jesli ciagle bedzie za wolno to cache'uj to zapytanie i powiedzmy raz na godzine usuwaj cache tak zeby trzymac w miare aktualne dane
Riklaunim
Baza danych nie jest kalkulatorem i jak będziesz miał dużo rekordów to zwykły COUNT będzie wolny. Rozwiązanie tego to denormalizacja licznika. Ilość komentarzy zapisujesz w tabeli newsa i inkrementujesz go przy dodaniu komentarza. Wyświetlając listę newsów nie musisz wtedy liczyć newsów na żywo.
phpion
Wydaje mi się, że zastosowanie w tym momencie podzapytania może okazać się wydajniejsze. Nie budujesz bowiem wielkiego złączenia tabel (w momencie, gdy do newsa jest wiele komentarzy) z grupowaniem:
  1. SELECT SQL_CALC_FOUND_ROWS newsy_id,newsy_data,newsy_czas,newsy_licznik,newsy_tytul,newsy_tekstskrocony,newsy_tekstrozszerzony,newsy_foto,fotosy_file,dzialy_nazwa,
  2.  
  3. -- Podzapytanie
  4. (SELECT COUNT(komentarze_id) FROM komentarze WHERE komentarze.komentarze_news = newsy.newsy_id AND komentarze.komentarze_status = '1') AS licznik
  5. --
  6.  
  7. FROM newsy LEFT JOIN fotosy ON (fotosy_id=newsy_foto) LEFT JOIN dzialy ON (dzialy_id=newsy_dzial) WHERE newsy_status='1' ORDER BY newsy_data DESC, newsy_czas DESC LIMIT 0, 25

Jeśli się nie machnąłem to powinno działać. Daj znać jak wyglądają czasy wykonań obu zapytań.
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.