Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL][PHP]Optymalizacja zapytania SQL w skrypcie PHP
yalus
post
Post #1





Grupa: Zarejestrowani
Postów: 281
Pomógł: 0
Dołączył: 8.07.2005
Skąd: EU

Ostrzeżenie: (0%)
-----


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ęć (IMG:style_emoticons/default/facepalmxd.gif)


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


pozdrawiam



Go to the top of the page
+Quote Post
nospor
post
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Do tego celu uzywa sie LEFT JOIN users_images
a potem group by oraz count
Go to the top of the page
+Quote Post
aras785
post
Post #3





Grupa: Zarejestrowani
Postów: 859
Pomógł: 177
Dołączył: 29.10.2009

Ostrzeżenie: (0%)
-----


  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;
Go to the top of the page
+Quote Post
yalus
post
Post #4





Grupa: Zarejestrowani
Postów: 281
Pomógł: 0
Dołączył: 8.07.2005
Skąd: EU

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
aras785
post
Post #5





Grupa: Zarejestrowani
Postów: 859
Pomógł: 177
Dołączył: 29.10.2009

Ostrzeżenie: (0%)
-----


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


Ten post edytował aras785 6.04.2016, 11:54:36
Go to the top of the page
+Quote Post
yalus
post
Post #6





Grupa: Zarejestrowani
Postów: 281
Pomógł: 0
Dołączył: 8.07.2005
Skąd: EU

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
nospor
post
Post #7





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




No jesli masz duuuuuzo userow i duuuuuzo zdjec do userow i jeszcze dodatkowo nie zalozyles indeksow na te tabele, to skrypt moze trwac dlugo
Go to the top of the page
+Quote Post
yalus
post
Post #8





Grupa: Zarejestrowani
Postów: 281
Pomógł: 0
Dołączył: 8.07.2005
Skąd: EU

Ostrzeżenie: (0%)
-----


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?



Go to the top of the page
+Quote Post
nospor
post
Post #9





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




No wypadaloby zalozyc index na users_id
Go to the top of the page
+Quote Post
yalus
post
Post #10





Grupa: Zarejestrowani
Postów: 281
Pomógł: 0
Dołączył: 8.07.2005
Skąd: EU

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/wink.gif)
nie zdawałem sobie sprawy za co odpowiadają indeksy, trochę poczytałem i dalej będę drążyć temat indeksów (IMG:style_emoticons/default/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
Go to the top of the page
+Quote Post
koodo218
post
Post #11





Grupa: Zarejestrowani
Postów: 114
Pomógł: 25
Dołączył: 22.11.2015

Ostrzeżenie: (0%)
-----


Zapewne te, które będzie wykonywać się krócej - sprawdź czas w jakim się wykonuje. Przy małych bazach i tak niezauważalne.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 09:48