nazarpc
@nazarpc
Open Source enthusiast

Нужна помощь в оптимизации SQL запроса

Есть две таблицы: одна с фильмами, вторая с их расписанием. Нужно выбирать фильмы, сортируя по количеству сеансов этого фильма на определённый промежуток времени. То есть фильмы отображаются все, даже без сеансов, но те, у которых больше сеансов — впереди.
Фильмов несколько тысяч, расписаний — сотни тысяч записей.
Сейчас вот такой запрос:

SELECT `m`.`id` FROM `movies` AS `m` LEFT JOIN `schedule` AS `s` ON `m`.`id` = `s`.`movie` AND `s`.`date` > '2012-11-01' AND `s`.`date` <= '2012-11-02' GROUP BY `m`.`id` ORDER BY COUNT(`s`.`movie`) DESC LIMIT 0, 10

Работает долго, проблема в COUNT(`s`.`movie`), который судя по всему вычисляется для каждого фильма отдельно.
Можно ли это каким-то образом оптимизировать?

P.S. В прошлый раз помогли, спасибо, очень надеюсь на мощь коллективного разума!)
  • Вопрос задан
  • 3585 просмотров
Решения вопроса 1
startsevdenis
@startsevdenis
Попробуйте так, синтаксис не проверял, но по идее должно работать.
SELECT `m`.`id` FROM `movies` AS `m` LEFT JOIN (SELECT `s`.`movie`, COUNT(`s`.`movie`) as count FROM `schedule` as `s` WHERE `s`.`date` > '2012-11-01' AND `s`.`date` <= '2012-11-02' GROUP BY `s`.`movie`) as j ON `j`.`movie` = `m`.`id` ORDER BY `j`.`count`
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@edogs
Зачем здесь вообще join если Вы выбираете только m.id который у Вас равен s.movie? Для того что бы выбрать фильмы без расписания тоже? Имхо из-за этого могут получиться избыточные данные.

select count(*), movie from schedule where date>'2012-11-01' and date<='2012-11-02' order by count(*) desc limit 10
Так Вы выберите все фильмы с расписанием. А потом тупо дополните их запросом к movies что бы выбрать все фильмы вообще и выкините из них результаты первого запроса. Сумма и будет нужным результатом.
Ответ написан
Комментировать
Methos
@Methos
Попробуйте так:

SELECT DISTINCT `m`.`id` 
FROM `movies` AS `m` 
LEFT JOIN (
 (
  SELECT `s`.`movie` FROM `schedule`
   WHERE `s`.`date` > '2012-11-01' AND `s`.`date` <= '2012-11-02' 
) AS `s` ON (
   `s`.`movie` = `m`.`id`
)
ORDER BY COUNT(`s`.`movie`) DESC 
LIMIT 0, 10
Ответ написан
DenisOgr
@DenisOgr
Developer
конструкция LEFT JOIN должна быть только с одним условием.
Если есть несколько нужно использовать WHERE
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы