Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Optymalizacja zapytania SQL w skrypcie PHP
Forum PHP.pl > Forum > Przedszkole
yalus
Witam,

czy można jakoś zoptymalizować poniższe działanie skryptu php, zastanawiam się jakby to zrobić:


tabele:

users
id | imie | nazwisko |
------------------------
1 | jan | kowalski |


users_images
users_id | image |
-----------------------
1 | img1.jpg
1 | img2.jpg
1 | img3.jpg



  1. function get_total_images($we)
  2. {
  3. $sql="select users_id, count(*) from users_images where users_id = ".$we;
  4. $result1 = mysql_query($sql);
  5. $row = mysql_fetch_array($result1);
  6. return $row[1];
  7. }
  8.  
  9.  
  10. $sql = "select * from users";
  11.  
  12. $result = mysql_query($sql);
  13.  
  14. while ($row = mysql_fetch_array($result))
  15. {
  16. echo "Imie: ".$row['imie']."<br>Nazwisko: ".$row['nazwisko']."<br>Ilość zdjęć: ".get_total_images($row['id']);
  17. }




niby to jakoś działa ale przez zastosowanie funkcji get_total_images zwiększa mi się liczba zapytań do bazy bo każdy wyświetlany rekord "odpytuje" baze ile dany użytkownik ma zdjęć

np.
mając 1000 użytkowników i chcąc ich wyświetlić to w pętli WHILE muszę odpalić 1000 razy jedno zapytanie aby sprawdzić ile posiadają zdjęć facepalmxd.gif


czy dało by się użyć tylko jednego zapytania sql aby wyświetlić użytkowników oraz liczbę zdjęć?


pozdrawiam



nospor
Do tego celu uzywa sie LEFT JOIN users_images
a potem group by oraz count
aras785
  1. select users.*,count(users_images.id) as ilosc_zdjec from users left join users_images on users.id=users_images.users_id group by users.id;
yalus
super, dziękuję bardzo za pomoc,

ale mam pytanie odnośnie tego zapytania które podałeś:


spróbowałem je odpalić ale niestety skrypt się zawiesza kończąc działenie informacją o przekroczeniu czasu na wykonanie skryptu

czy nie ma w nim jakiegoś błędu?

zmieniłem je trochę dodając limit i aby pobieral z tabeli users tylko imie

  1. SELECT users.imie,count(users_images.id) AS ilosc_zdjec FROM users LEFT JOIN users_images ON users.id=users_images.users_id GROUP BY users.id LIMIT 100
aras785
  1. $sql = 'SELECT users.*,count(users_images.id) AS ilosc_zdjec FROM users LEFT JOIN users_images ON users.id=users_images.users_id GROUP BY users.id';
  2.  
  3. $result = mysql_query($sql);
  4.  
  5. while ($row = mysql_fetch_array($result)) {
  6. echo "Imie: ".$row['imie']."<br>Nazwisko: ".$row['nazwisko']."<br>Ilość zdjęć: ".$row['ilosc_zdjec'];
  7. }
yalus
jeszcze raz dzięki za pomoc,


dla mnie zapytanie na oko wygląda że jest poprawne ale niestety skrypt się zawiesza (przekroczenie czasu),

może w zapytaniu jest jakiś błąd? niestety ja nie jestem w stanie tego sprawdzić, pomożesz jeszcze raz?



Pozdrawiam
nospor
No jesli masz duuuuuzo userow i duuuuuzo zdjec do userow i jeszcze dodatkowo nie zalozyles indeksow na te tabele, to skrypt moze trwac dlugo
yalus
userow jest 43000

  1. CREATE TABLE `users` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `first_name` char(50) DEFAULT NULL,
  4. `last_name` char(25) DEFAULT NULL,
  5. `email` char(25) DEFAULT NULL
  6. PRIMARY KEY (`id`),
  7. UNIQUE KEY `id` (`id`),
  8. UNIQUE KEY `email` (`email`),
  9. UNIQUE KEY `profile_name_2` (`profile_name`)
  10. ) ENGINE=InnoDB DEFAULT CHARSET=latin2



a zdjec 82000

  1. CREATE TABLE `images` (
  2. `users_id` int(11) DEFAULT NULL,
  3. `images` char(100) DEFAULT NULL
  4. ) ENGINE=InnoDB DEFAULT CHARSET=latin2



a czy z indeksami można coś pozmieniac w tych tabelach?



nospor
No wypadaloby zalozyc index na users_id
yalus
założyłem indeks na users_id (PRIMARY KEY) i różnica jest kolosalna, bez jakiegokolwiek limitu wyświetla mi wszystkich userów w mgnieniu oka, albo nawet szybciej wink.gif
nie zdawałem sobie sprawy za co odpowiadają indeksy, trochę poczytałem i dalej będę drążyć temat indeksów wink.gif

mam jeszcze jedno pytanie, które zapytanie będzie "lepsze" aby policzyć liczbę rekordów w tabeli:


  1. SELECT COUNT(*) AS total FROM users
  2.  
  3. czy
  4.  
  5. SELECT COUNT(id) AS total FROM users
koodo218
Zapewne te, które będzie wykonywać się krócej - sprawdź czas w jakim się wykonuje. Przy małych bazach i tak niezauważalne.
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.