Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Optymalizacja zaawansowanego zapytania, zabija serwer - strona ładuje się 10 sekund
Natalka
post
Post #1





Grupa: Zarejestrowani
Postów: 59
Pomógł: 6
Dołączył: 28.10.2009
Skąd: że znowu...

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


Mam pewien problem z zapytaniem, które strasznie zamula mi stronę.


Na stronie chcę pobrać

Wszystkie obrazki z bazy danych które zostały polubione powyżej 3 razy.


Moje zapytanie wygląda tak:
Kod
SELECT * FROM obrazek WHERE id in (SELECT id_obrazek FROM loveit HAVING count(loveit.id) > 3 ) ORDER BY id desc LIMIT $ilosc



Tabela obrazek - zawiera listę wszystkich obrazków

pola w bazie
id - nr id obrazka


Tabela loveit - zawiera listę wszystkich osób które lubią obrazek

pola w bazie
id_obrazek - nr id obrazka


Wiem że problem jest dokładnie tutaj
Kod
WHERE id in (SELECT id_obrazek FROM loveit HAVING count(loveit.id) > 3 )


Bo gdy usunę tę cześć działa bez problemu.

Czy jest ktoś w stanie mi pomóc w jaki sposób mogę to zoptymalizować?

Ten post edytował Natalka 15.05.2011, 14:08:14
Go to the top of the page
+Quote Post
melkorm
post
Post #2





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

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


Spróbuj tak:
  1. SELECT * FROM obrazek o INNER JOIN loveit l ON o.id=l.id_obrazek GROUP BY l.id_obrazek HAVING count(l.id_obrazek) > 3 ORDER BY o.id DESC LIMIT $ilosc


Podaj też zrzuty struktur tabel, może indeksy da się poprawić.


--------------------
Go to the top of the page
+Quote Post
Tomplus
post
Post #3





Grupa: Zarejestrowani
Postów: 1 879
Pomógł: 230
Dołączył: 20.03.2005
Skąd: Będzin

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


Być może sprawa nie dot. zapytania,tylko samej bazy danej, może trzeba zmienić mechanizm obsługi bazy gdzie jest wiele zapytać.


I warto też ograniczyć pierwsze pole SELECT o kolumny które będziemy korzystać.

Ten post edytował Tomplus 15.05.2011, 14:13:23
Go to the top of the page
+Quote Post
Natalka
post
Post #4





Grupa: Zarejestrowani
Postów: 59
Pomógł: 6
Dołączył: 28.10.2009
Skąd: że znowu...

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


Już testuję Twoje zapytanie


/** sprawdzone **/

Działa dużo szbciej, już nie zabija tak strony

Czy można jeszcze coś ulepszyć w mojej bazie danych ?


A czy mógłby ktoś jeszcze podpowiedzieć co takiego źle robiłam? Czemu aż tak bardzo moje zapytanie zamulało stronę?



A Baza wygląda tak:


Kod
CREATE TABLE IF NOT EXISTS `obrazek` (
  `id` int(9) NOT NULL AUTO_INCREMENT,
  `tytul` text NOT NULL,
  `opis` text NOT NULL,
  `skad` text NOT NULL,
  `obrazek` text NOT NULL,
  `obrazekmini` text NOT NULL,
  `user_id` int(9) NOT NULL,
  `raport` int(1) DEFAULT '0',
  `dodanydata` varchar(20) NOT NULL,
  `plikURL` text NOT NULL,
  `typ` enum('obrazek','video') NOT NULL DEFAULT 'obrazek',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin2 AUTO_INCREMENT=2604;



Kod
CREATE TABLE IF NOT EXISTS `loveit` (
  `id` int(9) NOT NULL AUTO_INCREMENT,
  `id_obrazek` int(9) NOT NULL,
  `id_user` int(9) NOT NULL,
  `datadodania` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin2 AUTO_INCREMENT=4450;


Ten post edytował Natalka 15.05.2011, 14:23:08
Go to the top of the page
+Quote Post
melkorm
post
Post #5





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

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


Załóż indeksy na : user_id ( w obu tabelkach ) , id_obrazek, datadodania i dodanydata (przy okazji powinnaś te dwa pola zmienić na int/timestamp/date/datetime, bo varchar jest tutaj nie na miejscu).

edit:
Cytat
A czy mógłby ktoś jeszcze podpowiedzieć co takiego źle robiłam? Czemu aż tak bardzo moje zapytanie zamulało stronę?


Ponieważ dla każdego rekordu który pobierałaś odbywało się zapytanie
  1. SELECT id_obrazek FROM loveit HAVING count(loveit.id) > 3

które przelatywało za każdym razem całą tabelkę loveit.

I ogólnie IN'y + (sub)COUNTY są obciążające, dla tego jeżeli jest taka możliwość trzeba używać JOIN'ów które są o niebo szybsze.


edit2:
Dlaczego te pola są typu TEXT ? Nie wystarczyłby varchar(255/500) ?
Cytat
`tytul` text NOT NULL,
`skad` text NOT NULL,
`obrazek` text NOT NULL,
`obrazekmini` text NOT NULL,
`plikURL` text NOT NULL,


Jeszcze a propo indeksów możesz założyć na pole typ.

Ten post edytował melkorm 15.05.2011, 14:30:39


--------------------
Go to the top of the page
+Quote Post
Natalka
post
Post #6





Grupa: Zarejestrowani
Postów: 59
Pomógł: 6
Dołączył: 28.10.2009
Skąd: że znowu...

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


Cytat(melkorm @ 15.05.2011, 15:23:49 ) *
Załóż indeksy na : user_id ( w obu tabelkach ) , id_obrazek, datadodania i dodanydata (przy okazji powinnaś te dwa pola zmienić na int/timestamp/date/datetime, bo varchar jest tutaj nie na miejscu).



Hmm..
Głupio mi przyznać bo nigdy nie stosowałam indeksów prócz dla id.

O co w nich chodzi?
Muszę ustawić nazwę klucza (czy ona ma jakiś związek z zapytaniem?)

Czy indeksy przyśpieszają pobieranie danych? Mam też inny duży serwis w którym niestety nie korzystam z indeksów, mimo że działa sprawnie.
A najwyższa pora zmienić swoje przyzwyczajenia i nauczyć się robić coś lepiej smile.gif

Bardzo dziękuje za pomoc,

Pola TEXT już zmienione smile.gif
Go to the top of the page
+Quote Post
melkorm
post
Post #7





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

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


Jest sporo wartościowych tekstów w internecie na temat Indeksów, w skrócie mogę powiedzieć że mówią one jak porządkować dane w tabeli co przyśpiesza ich pobieranie.
Ogólnie przyjmuję się taką zasadę że indeksy zakłada się na pola po których porządkujesz/grupujesz tabelę i na klucze obce( przy silniku InnoDB jest to wymóg).

Btw. Zainteresuj się silnikiem InnoDB i relacjami.

Cytat
Muszę ustawić nazwę klucza (czy ona ma jakiś związek z zapytaniem?)


Nie jest ona ważna.

Cytat
Czy indeksy przyśpieszają pobieranie danych?


Gdybyś z większego serwisu/forum wywaliła indeksy sądzę że by nawet nie ruszył biggrin.gif - czyli tak, przyśpieszają i to czasami bardzo.

P.S. To nie jest zaawansowane zapytanie wink.gif

Ten post edytował melkorm 15.05.2011, 14:41:32


--------------------
Go to the top of the page
+Quote Post
Natalka
post
Post #8





Grupa: Zarejestrowani
Postów: 59
Pomógł: 6
Dołączył: 28.10.2009
Skąd: że znowu...

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


Cytat(melkorm @ 15.05.2011, 15:37:54 ) *
P.S. To nie jest zaawansowane zapytanie wink.gif



Nie dla wszystkich smile.gif łączenie kilku tabel to dla mnie największy problem mimo przestudiowania książki z mysql

Jest to coś czego nie potrafię zrozumieć i sobie z tym nie radzę więc to dla mnie naprawdę trudne zapytanie.

Jeszcze raz wielkie dzięki, muszę w końcu się przysiąść do tego na poważnie by nie zanudzać swoimi problemami


Dzięki za pomoc smile.gif
Go to the top of the page
+Quote Post
melkorm
post
Post #9





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

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


Cytat
Nie dla wszystkich łączenie kilku tabel to dla mnie największy problem mimo przestudiowania książki z mysql

Jest to coś czego nie potrafię zrozumieć i sobie z tym nie radzę więc to dla mnie naprawdę trudne zapytanie.

Ćwiczyć, ćwiczyć wink.gif

Cytat
Jeszcze raz wielkie dzięki, muszę w końcu się przysiąść do tego na poważnie by nie zanudzać swoimi problemami

Spoko, przynajmniej mamy co robić w niedzielne popołudnie biggrin.gif

Cytat
Dzięki za pomoc smile.gif

Nie ma za co smile.gif


--------------------
Go to the top of the page
+Quote Post
Fifi209
post
Post #10





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

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


Dla autora tematu pozwolę sobie zalinkować do video artów:
uw-team mysql



--------------------
Zainteresowania: C#, PHP, JS, SQL, AJAX, XML, C dla AVR
Chętnie pomogę, lecz zanim napiszesz: Wujek Google , Manual PHP
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 19.08.2025 - 23:13