Wpis z mikrobloga

#mysql #programowanie

Cześć mam takie zapytanie
SELECT games.gid,games.value,games.itemcount, games.hash,games.salt,games.winnerp, users.username,users.avatar, (SELECT SUM(price) FROM items WHERE items.gid = games.gid AND items.uid = games.wid) as dd FROM games INNER JOIN users ON games.wid=users.uid ORDER BY gid DESC LIMIT 15
pokolorowane: https://gist.github.com/cymruu/37396148a5d38c9107a69a40fbd072da
I działa dobrze, ale niestety wykonuje się 1,5 sekundy a wydaje mi się, że to dużo za dużo. W jaki sposób mogę to zoptymalizować?
  • 26
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@wytrzzeszcz: jako że na bazach się niezbyt znam bynajmniej na ich wydajności, to ten join ma n^2, czy każdy join ma n^2? I nie znasz może jakiegoś fajnego artykułu o tym? czego unikać? co robić? (ale książki mnie nie interesują, chce tylko coś małego dla zaspokojenia ciekawości)
  • Odpowiedz
@wytrzzeszcz: a hashować się nie da (znaczy się, czy silnik bazy nie może hashować)? mam dane i to po czym łączysz, z obu tabel, co nie pasuje to wrzucam do hashmapy i wtedy kolejny element może znaleźć pasujący element w hashmape bo klucz jest taki sam bo w końcu po nim łączysz? A wyszukiwanie w hashmapie już powinno być szybsze, więc już zależnie od szczęśnie od N do N^2, gdzie
  • Odpowiedz
@sokytsinolop: Chyba się optymalizacja gubi na tym, że nie wie dla jakich gid ma liczyć sumy i buduje całą tabelę przed sortowaniem i wyświetleniem ostatnich 15. Tego selecta na sumy dołączyłbym przez JOIN (spróbuj też podzapytaniem ograniczyć wyniki wcześniej dając wynik jako główną tabelę z ORDER BY + LIMIT).
  • Odpowiedz
@sokytsinolop: Zrobi 15 dowolnych wierszy i już wiadomo, że więcej nie trzeba. Żeby wyłowić 15 konkretnych musi mieć najpierw wszystkie. Zwłaszcza, że JOIN będzie filtrował te niepasujące.
  • Odpowiedz
@MQs:
SELECT games.gid,games.value,games.itemcount, games.hash,games.salt,games.winnerp, users.username,users.avatar, (SELECT SUM(price) FROM items WHERE items.gid = games.gid AND items.uid = games.wid) as dd FROM games INNER JOIN users ON games.wid=users.uid
bez limit i bez order by - 0.16s
limit 200,500 - 0.1s
order by games gid - 1.7096s
order by games gid, limit 15
  • Odpowiedz
@sokytsinolop: Jeśli sortowanie spowalnia bez względu na ilość wierszy to problemu bym szukał w indeksach. Zobacz co wyrzuca EXPLAIN EXTENDED SELECT...
  • Odpowiedz
no Join ma złożoność czasową n^2 więc nie jest kolorowo


@wytrzzeszcz: Nie można tak na to patrzeć. Istnieją różne algorytmy dla joinów, istnieją indeksy, planner decyduje o tym kiedy zostanie join użyty.
  • Odpowiedz
SELECT games.gid,games.value,games.itemcount, games.hash,games.salt,games.winnerp, users.username,users.avatar, (SELECT SUM(price) FROM items WHERE items.gid = games.gid AND items.uid = games.wid) as dd FROM games INNER JOIN users ON games.wid=users.uid ORDER BY gid DESC LIMIT 15


@plushy: nadal 1.8s :/
  • Odpowiedz