Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Optymalizacja zapytania
wlamywacz
post
Post #1





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Witam

Struktura tabel:
  1. CREATE TABLE IF NOT EXISTS `pages` (
  2. `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `url` varchar(200) NOT NULL,
  4. `lastpr` smallint(2) NOT NULL,
  5. `pr` smallint(2) NOT NULL,
  6. `updateip` tinyint(1) UNSIGNED NOT NULL,
  7. `ip` bigint(20) UNSIGNED NOT NULL,
  8. `categoryid` int(11) UNSIGNED NOT NULL,
  9. `lastcheck` datetime NOT NULL,
  10. `updatepr` tinyint(1) UNSIGNED NOT NULL,
  11. `googlelastupdatesite` datetime NOT NULL,
  12. `googleupdatesite` tinyint(1) UNSIGNED NOT NULL,
  13. `googlesite` bigint(20) UNSIGNED NOT NULL,
  14. `yahoolastupdatesite` datetime NOT NULL,
  15. `yahooupdatesite` tinyint(1) UNSIGNED NOT NULL,
  16. `yahoosite` bigint(20) UNSIGNED NOT NULL,
  17. `yahoolastupdatebl` datetime NOT NULL,
  18. `yahooupdatebl` tinyint(1) UNSIGNED NOT NULL,
  19. `yahoobl` bigint(20) UNSIGNED NOT NULL,
  20. `information` text NOT NULL,
  21. `ping` int(11) NOT NULL,
  22. `lastping` datetime NOT NULL,
  23. PRIMARY KEY (`id`),
  24. UNIQUE KEY `id` (`id`)
  25. )

  1. CREATE TABLE IF NOT EXISTS `status` (
  2. `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `pageid` bigint(20) UNSIGNED NOT NULL,
  4. `date` datetime NOT NULL,
  5. `server` tinyint(1) NOT NULL,
  6. `php` tinyint(1) NOT NULL,
  7. UNIQUE KEY `id` (`id`),
  8. KEY `pageid` (`pageid`,`date`)
  9. )

  1.  
  2. CREATE TABLE IF NOT EXISTS `categories` (
  3. `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  4. `name` varchar(80) NOT NULL,
  5. PRIMARY KEY (`id`),
  6. UNIQUE KEY `id` (`id`)
  7. )

Zapytanie:
  1. SELECT p.`id`, p.`url`, p.`ip`, p.`lastpr`, p.`pr`, p.`googlesite`, p.`yahoosite`, p.`yahoobl`, p.`ping`, p.`information`, p.`categoryid` AS `category`, c.`name` AS `categoryname`, s.`server`, s.`php`, INET_NTOA(p.`ip`) AS `ip`, (SELECT COUNT(st.`id`) FROM `status` AS `st` WHERE st.`pageid` = p.`id` AND (st.`server` = 0 OR st.`php` = 0) AND DATE_ADD(st.`date`, INTERVAL 7 DAY) > NOW()) AS `errors` FROM `pages` AS `p` LEFT JOIN `categories` AS `c` ON c.`id` = p.`categoryid` LEFT JOIN `status` AS `s` ON (s.`id` = (SELECT `id` FROM `status` WHERE `pageid` = p.id ORDER BY `date` DESC LIMIT 1))


Niestety w tabeli status ilość rekordów wynosi 500 tysięcy do miliona może nawet kilku w ekstremalnych przypadkach. Całe zapytanie wykonuje się około 2,5 sekundy przy 400k rekordów. Wąskimi gardłami w tym zapytaniu są te dwa pod zapytania jednak niezbyt mam pojęcie jak się ich pozbyć i zastąpić czymś bardziej optymalnym. Z góry dziękuje za pomoc.
Go to the top of the page
+Quote Post
patryczakowy
post
Post #2





Grupa: Zarejestrowani
Postów: 420
Pomógł: 44
Dołączył: 22.10.2008

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


  1. SELECT `id` FROM `status` WHERE `pageid` = p.id ORDER BY `date` DESC LIMIT 1

Po co tu order by??
z tego co pamiętam to lepiej zamiast NOW() w php wygenerować datę i dać do zapytania
Go to the top of the page
+Quote Post
wlamywacz
post
Post #3





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Bo muszę pobrać najmłodszy rekord.
Go to the top of the page
+Quote Post
Mchl
post
Post #4





Grupa: Zarejestrowani
Postów: 855
Pomógł: 145
Dołączył: 17.07.2008
Skąd: High Memory Area

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


Masz podzapytania skorelowane, co zawsze jest wolne.
http://dev.mysql.com/doc/refman/5.1/en/cor...subqueries.html

Spróbuj to przepisać tak, żeby tego uniknąć (w większości przypadków da się)
Go to the top of the page
+Quote Post
wlamywacz
post
Post #5





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Użyje chyba nadmiarowych danych aby zwiększyć wydajność tego zapytania.
Go to the top of the page
+Quote Post
eccocce
post
Post #6





Grupa: Zarejestrowani
Postów: 165
Pomógł: 5
Dołączył: 10.07.2008
Skąd: Wrocław

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


Cytat(Mchl @ 16.06.2010, 20:05:26 ) *
Masz podzapytania skorelowane, co zawsze jest wolne.
http://dev.mysql.com/doc/refman/5.1/en/cor...subqueries.html

Spróbuj to przepisać tak, żeby tego uniknąć (w większości przypadków da się)

Masz może jakieś linki na ten temat? Bo też często używam zapytań skorelowanych (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
Mchl
post
Post #7





Grupa: Zarejestrowani
Postów: 855
Pomógł: 145
Dołączył: 17.07.2008
Skąd: High Memory Area

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


Manual rozdział 7.2.
http://dev.mysql.com/doc/refman/5.1/en/query-speed.html

Ten post edytował Mchl 18.06.2010, 18:33:47
Go to the top of the page
+Quote Post
yevaud
post
Post #8





Grupa: Zarejestrowani
Postów: 471
Pomógł: 89
Dołączył: 29.07.2008
Skąd: Warszawa

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


lepiej zamiast NOW() wrzucic statyczna date z php, NOW jest niedeterministyczne i nie bardzo mysql potrafi je cachowac
jesli wrzucisz zamiast tego jakas stala, to wprawdzie zapytanie za pierwszym razem wykona sie 2.5 sec, ale za drugim juz 0.1 (IMG:style_emoticons/default/winksmiley.jpg)

wydaje mi sie ze ten count nie musi byc w podzapytaniu, chyba wystarczy zwykle grupowanie po p.id
najmniejsze statusy drugiego podzapytania przygotowalbym sobie wczesniej w tabeli tymczasowej i sklejal to inner

zawsze gdy robilem dane nadmiarowe to pozniej zalowalem (IMG:style_emoticons/default/smile.gif)

Ten post edytował yevaud 19.06.2010, 00:13:13
Go to the top of the page
+Quote Post
wookieb
post
Post #9





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




A może nauczysz się formatować zapytanie tak żeby DAŁO JE SIĘ CZYTAĆ?

Po drugie nie masz założonych żadnych indeksów więc najwyższa pora o nich pomyśleć.
Uprzedzam pytania "na co założyć?". Nie jesteśmy w stanie DOBRZE tego określić ponieważ do analizy potrzebne jest znacznie więcej niż twoje jedno zapytanie.
Go to the top of the page
+Quote Post
yevaud
post
Post #10





Grupa: Zarejestrowani
Postów: 471
Pomógł: 89
Dołączył: 29.07.2008
Skąd: Warszawa

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


nie wiem dlaczego zalozylem milczaco, ze indeksy pozakladane sa oddzielnie (IMG:style_emoticons/default/smile.gif)
polecam prosty wpis o optymalizacji do przetrawienia

http://net.tutsplus.com/tutorials/other/to...best-practices/
Go to the top of the page
+Quote Post
wlamywacz
post
Post #11





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Poradziłem sobie już z nadmiarowymi danymi. Jeśli ktoś otworzy oczy to zauważy iż indexy są założone, bez nich zapytanie trwało by wieki. Pozdrawiam i dziękuje za pomoc. Temat do zamknięcia. (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
Mchl
post
Post #12





Grupa: Zarejestrowani
Postów: 855
Pomógł: 145
Dołączył: 17.07.2008
Skąd: High Memory Area

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


Pytanie, czy to najlepsze indeksy jakie się da zrobić (IMG:style_emoticons/default/winksmiley.jpg)
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: 18.09.2025 - 15:55