Optymalizacja zapytania MySQL

0

Mam takie zapytanie:

SELECT W.NAZWA, SUM(CASE WHEN W.WYSLANY = 1 THEN 1 ELSE 0 END) AS WYSLANE
FROM WIADOMOMOSCI W
INNER JOIN MAILING M ON W.CID =M.ID
WHERE M.TYP = 'KOSZTOWY'
GROUP BY M.CID
ORDER BY M.ILOSC;

  • po zakomentowaniu order by wykonuje się bardzo szybko, na polu ilosc nie ma indeksu
  • natomiast bez komentowania order by, ale za to po wyrzuceniu sum(case..) wykonuje się dwa razy szybciej

Jakieś pomysły w czym moze tkwić problem i jak to zoptymalizować?

1
  1. SUM(CASE WHEN W.WYSLANY = 1 THEN 1 ELSE 0 END) - to nie jest to samo, co sum(w.wyslany)?

  2. Masz indeksy na wiadomosci.cid, mailing.id oraz mailing.typ?

  3. wykonuje się dwa razy szybciej - ile to jest dwa razy szybciej? Ile masz wierszy w tych tabelach?

  4. Odpal explain na tym zapytaniu.

  5. NIE PISZ ZAPYTAŃ W TAKI SPOSÓB, BO WIELKIE LITERY WCALE NIE UŁATWIAJĄ CZYTANIA TEKSTU, CHYBA ŻE MASZ PROBLEM Z WZROKIEM I NIEDOWIDZISZ, ALE W TAKIM WYPADKU POWINIENEŚ ZWIĘKSZYĆ ROZMIAR FONTU W EDYTORZE, A NIE PISAĆ CAPS-LOCKIEM.

1

Ech nie mam pod ręką mysql ale czy to zapytanie aby na pewno jest poprawne? Grupujesz po M.CID a sortujesz po M.ILOSC jednak w select masz W.NAZWA, SUM(CASE WHEN W.WYSLANY = 1 THEN 1 ELSE 0 END) jeśli taka konstrukcja rzeczywiście działa na mysql to ja się pytam jak?

Finalnie z orderem czasem bywa problem i można to obejść na kilka sposobów ale po pierwsze musisz podać plan zapytania po drugie mieć poprawne zapytanie bo śmiem twierdzić, że to co podałeś raczej się nie odpali :) W oracle i postgresql rzuci Ci wyjątkiem niepoprawny group by.

0
woolfik napisał(a):

Ech nie mam pod ręką mysql ale czy to zapytanie aby na pewno jest poprawne? Grupujesz po M.CID a sortujesz po M.ILOSC jednak w select masz W.NAZWA, SUM(CASE WHEN W.WYSLANY = 1 THEN 1 ELSE 0 END) jeśli taka konstrukcja rzeczywiście działa na mysql to ja się pytam jak?

Finalnie z orderem czasem bywa problem i można to obejść na kilka sposobów ale po pierwsze musisz podać plan zapytania po drugie mieć poprawne zapytanie bo śmiem twierdzić, że to co podałeś raczej się nie odpali :) W oracle i postgresql rzuci Ci wyjątkiem niepoprawny group by.

Faktycznie trochę namieszałam:
select M.NAZWA, SUM(CASE WHEN W.WYSLANY = 1 THEN 1 ELSE 0 END) AS WYSLANE
from WIADOMOMOSCI W
inner join MAILING M ON W.CID = M.ID
where M.TYP = 'KOSZTOWY'
group by W.CID
order by M.ILOSC;

0

Jak Ci zamula zapytanie, to:

  1. Dodaj przed tym zapytaniem explain extended i je wykonaj. Wklej wynik różnych kombinacji, o których mowa.
  2. Wklej wynik zapytania show index from nazwa_tabeli dla każdej tabeli, która bierze udział w zapytaniu.
2
select M.NAZWA, SUM(W.WYSLANY) AS WYSLANE
from WIADOMOSCI W
inner join MAILING M ON W.CID = M.ID AND M.TYP = 'KOSZTOWY'
group by M.ID

Tego order nie możesz mieć.
Co zmieniłem:

  1. wywaliłem WHERE na rzecz JOIN
  2. GROUP BY po pewnie indeksowanym polu
  3. zmienilem SUM
  4. wywałiłem ORDER BY. Jeśli chcesz mieć ten order by, to daj to pole do wyników, pogrupuj po nim i wtedy order by
    powinno być szybciej. Duzo

1 użytkowników online, w tym zalogowanych: 0, gości: 1