2016-09-02 2 views
-2

Я хотел бы спросить, как я могу оптимизировать этот запрос:Как можно оптимизировать этот запрос MySQL

select 
    h.jmeno hrac, 
    n1.url hrac_url, 
    t.nazev tym, 
    n2.url tym_url, 
    ss.pocet_zapasu zapasy, 
    ss.pocet_minut minuty, 
    s.celkem_golu goly, 
    s.zk, 
    s.ck 
from 
    hraci h 
left join 
    (
     select 
      hrac_id, 
      tym_id, 
      count(minut_celkem) pocet_zapasu, 
      sum(minut_celkem) pocet_minut 
     from 
      statistiky_stridani ss 
     join 
      zapasy z 
       on z.id = ss.zapas_id 
     join 
      souteze s 
       on s.id = z.soutez_id 
     join 
      souteze_nazev sn 
       on sn.id = s.soutez_id 
     where 
      s.rocnik_id = 2 
     group by 
      hrac_id 
    ) ss on ss.hrac_id = h.id 
left join 
    (
     select 
      hrac_id, 
      tym_id, 
      sum(typ_id = 1 or typ_id = 3) as celkem_golu, 
      sum(typ_id = 4) as zk, 
      sum(typ_id = 5) as ck 
     from 
      statistiky st 
     join 
      zapasy z 
       on z.id = st.zapas_id 
     join 
      souteze s 
       on s.id = z.soutez_id 
     join 
      souteze_nazev sn 
       on sn.id = s.soutez_id 
     where 
      s.rocnik_id = 2 
     group by 
      hrac_id 
    ) s on s.hrac_id = h.id 
join 
    navigace n1 
     on n1.id = h.nav_id 
join 
    tymy t 
     on t.id = ss.tym_id 
join 
    navigace n2 
     on n2.id = t.nav_id 
order by 
    s.celkem_golu desc 
limit 
    10 

Поскольку запрос занимает около 1,5 - 2 секунды. Например, таблица statistiky_stridani имеет около 500 000 строк и статистики около 250 000 строк.

Это возвращает EXPLAIN: enter image description here

Спасибо за вашу помощь

+0

Хм, нет благодарности - но удачи – Strawberry

ответ

1
  1. Не используйте LEFT JOIN вместо JOIN если вы на самом деле не нужны пустые строки.

  2. Попробуйте переформулировать, потому что JOIN (SELECT ...) JOIN (SELECT ...) оптимизирован плохо.

  3. Не используйте тот же псевдоним (s) для двух разных таблиц; это смущает читателя.

  4. Добавить составной индекс INDEX(rocnik_id, soutez_id) в souteze.

  5. LEFT JOIN ... JOIN ... - Пожалуйста, добавьте скобки, чтобы показать, должен ли быть JOIN перед выполнением LEFT JOIN или после:

либо

FROM ... 
LEFT JOIN (... JOIN ...) 

или

FROM (... LEFT JOIN ...) 
JOIN ... 

Это может делают большую разницу в том, как оптимизатор выполняет запрос, который может изменить скорость.

Может быть больше предложений; работать через них и снова спрашивать (если он все еще «слишком медленный»).

+0

Согласитесь, что производные таблицы медленны на mysql, если вам нужно сделать это, заменив их на индексированные временные таблицы, тем больше будет работать, но, по крайней мере, некоторые улучшения могут быть сделаны. – Namphibian

Смежные вопросы