Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Optymalizacaja zapytania
Forum PHP.pl > Forum > Bazy danych > MySQL
GameMaker
Witajcie !

Poprawiam wyszukiwarkę portalową.
Problem tkwi w tym, że w godzinach szczytu, że zapytanie zaczyna zajeżdżać serwer.

Zapytanie, które jest aktualnie (przykład):

  1. SELECT SQL_CALC_FOUND_ROWS SQL_CACHE post.id, post.autor, post.date AS newsdate, short_story AS story, post.xfields AS xfields, title, descr, keywords, category, alt_name, comm_num AS comm_in_news, allow_comm, rating, flag, editdate, editor, reason, view_edit, count( search_wordmatch.news_id) AS count FROM search_wordlist, search_wordmatch, post WHERE ( search_wordlist.id = search_wordmatch.word_id AND search_wordmatch.news_id = post.id ) AND ( search_wordlist.word_text = 'układ' OR search_wordlist.word_text = 'zamknięty' ) AND ( category != 13 AND category != 44 AND category != 45 AND category != 46 ) GROUP BY search_wordmatch.news_id ORDER BY count DESC, news_read DESC LIMIT 0,20
  2.  


Przepisane zapytanie do innej postaci() :

  1. SELECT SQL_CACHE count( search_wordmatch.news_id) AS kant ,post.id, post.short_story, post.title, post.autor, post.date, post.category, post.comm_num, post.alt_name, post.descr FROM `search_wordlist`
  2. LEFT JOIN search_wordmatch ON search_wordlist.id = search_wordmatch.word_id
  3. LEFT JOIN post ON post.id = search_wordmatch.news_id WHERE (`category` NOT IN(13,44,45,35,46,53,70)) AND ( search_wordlist.word_text = 'Need' OR search_wordlist.word_text = 'for' OR search_wordlist.word_text = 'speed' )
  4. GROUP BY news_id
  5. ORDER BY kant DESC , news_id DESC
  6. LIMIT 0, 20


Indexy :

Tabela :

-- search_wordlist

http://scr.hu/1s02/bg4fo

-- search_wordmatch

http://scr.hu/1s02/1fxpz

-- post

http://scr.hu/1s02/tm1s9


EXPLAIN tego zapytania :

http://scr.hu/1s02/ljnq1


Jakie są wasze sugestie odnośnie optymalizacji takiego zapytania.
bpskiba
No tak od początku.....
Odpuszczę sobie analizę indeksów i strukturę tabel (widać kolega wie co się z tym robi closedeyes.gif ).
Odpalenie OPTIMIZE też pewnie jest jasne.
Pytanie o konfigurację serwera... Z mojego doświadczenia wynika, że olbrzymia ilość serwerów działa na ustawieniach domyślnych i zmiana tych ustawień rozwiązuje masę problemów.

Odnośnie meritum, czyli zapytania tutaj też jest olbrzymie pole do działania gdyż z mojego doświadczenia wynika, że silnik mysql pierwsze wykonuje złączenia i potem dopiero sortuje i grupuje złączone tabele - co siłą rzeczy wymaga mieszania dużą ilością danych. Stosując inne złączenia lub podzapytania nieraz uzyskiwałem stukrotny wzrost wydajności w stosunku do zapytań napisanych książkowo smile.gif

przykład:
- książkowo
  1. SELECT t1.a,t2.a
  2. FROM t1
  3. JOIN t2 ON t1.a=t2.a
  4. WHERE
  5. t1.c =2


alternatywa 1
  1. SELECT t1.a,t2.a
  2. FROM t1
  3. JOIN t2 ON t1.a=t2.a AND t1.c=2


alternatywa 2
  1. SELECT t3.a,t2.a
  2. FROM
  3. (SELECT a FROM t1 WHERE c=2) AS t3
  4. JOIN t2 ON t3.a=t2.a
GameMaker
Serwer, aktualnie nie działa na domyślnej konfiguracji, zostało dużo zmian wprowadzonych pod kątem optymalizacji serwera przez administratora.

Dzięki za podpowiedź.
redeemer
'Using temporary; Using filesort' -> spróbój przenieść TMPDIR do pamięci RAM. Dodatkowo dorób mechanizm cacheowania w warstwie aplikacji.
GameMaker
Aktualnie testuję takie zapytanie :

  1. SELECT SQL_CACHE post.id, short_story, title, autor, date, category,
  2. comm_num,
  3. alt_name,
  4. descr ,
  5. wyns.count AS trafnosc
  6. FROM
  7. (SELECT news_id ,
  8. count(search_wordmatch.news_id) AS COUNT
  9. FROM
  10. (SELECT id
  11. FROM search_wordlist
  12. WHERE (search_wordlist.word_text = 'Układ'
  13. OR search_wordlist.word_text = 'zamknięty')) AS list
  14. JOIN search_wordmatch ON search_wordmatch.word_id = list.id
  15. GROUP BY news_id) AS wyns
  16. JOIN post ON post.id = wyns.news_id
  17. WHERE (`category` NOT IN(13,44,45,35,46,53,70))
  18. ORDER BY `trafnosc` DESC
  19.  


I powiem, że czas wykonywania zmniejszył się 2 x.
bpskiba
Z tego, co widzę to zagnieździłeś zapytania. Nie koniecznie o to mi chodziło, ale jak sam widzisz to daje efekty smile.gif
Idea polega na tym, aby wybrać z tabeli to co jest potrzebne, a następnie łączyć ją z kolejną.



przenieś WHERE (`category` NOT IN(13,44,45,35,46,53,70)) do podzapytania
GameMaker
Zrobiłem mały update zapytania , ale przeniesienie where do podzapytania wyrzuca błąd.

  1.  
  2. SELECT SQL_CALC_FOUND_ROWS SQL_CACHE post.id, short_story, title, autor, date, category, comm_num, alt_name, descr , wyns.count AS trafnosc FROM (SELECT news_id ,count(search_wordmatch.news_id) AS count FROM (SELECT id, word_text FROM search_wordlist) AS list JOIN search_wordmatch ON search_wordmatch.word_id = list.id AND ( list.word_text = 'Arrow' ) GROUP BY news_id ) AS wyns JOIN dle_post ON post.id = wyns.news_id AND ( post.category NOT IN(13,44,45,35,46,53,70)) ORDER BY trafnosc DESC


bpskiba,

Chyba ,że miałeś inna rzecz na myśli.
Jako możesz to przytocz przykład.
bpskiba
najpierw próbujesz grupować, a potem dołączasz kolejną tabelę - i to zapewne powoduje błąd.
Jeśli chodzi o przykład, to przeanalizuj to co napisałem jako 'alternatywa2', czyli pierwsze kwerenda wybierająca w podzapytaniu i następnie do tego dołączona druga tabela
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.