Как сделать сортировку по голосам?

Всем привет! Есть у меня новости, у каждой новости есть кнопка "like". И вот нужно мне вытащить, скажем, самые популярные (где больше всего лайков) новости за неделю или за день. Структура БД такая: таблица новостей и таблица лайков, где каждый лайк сохранятется как отдельная запись.
Делаю вот такой запрос, и всё получается, но очень долго, аж 2 секунды:
SELECT n.`id`, 
(
     SELECT count(l.`id`) 
     FROM `like` l 
     WHERE n.`id` = l.`news_id` AND l.`date` > date_add(NOW(), INTERVAL -7 day)
) count_like 
FROM `news` n 
ORDER BY count_like DESC
LIMIT 0, 100

Помогите плз ускорить запрос...
  • Вопрос задан
  • 154 просмотра
Пригласить эксперта
Ответы на вопрос 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Если нужны новости, где ноль лайков:
SELECT `n`.`id`, IFNULL(`c`.`count`, 0)
  FROM `news` AS `n`
  LEFT JOIN (
    SELECT `news_id`, COUNT(*) AS `count`
      FROM `like`
      WHERE `date` > date_sub(NOW(), INTERVAL 7 day)
      GROUP BY `news_id`
    ) AS `c` ON `c`.`news_id` = `n`.`id`
  ORDER BY `c`.`count` DESC
  LIMIT 100

Если не нужны:
SELECT `news_id`, COUNT(*) AS `count`
  FROM `like`
  WHERE `date` > date_sub(NOW(), INTERVAL 7 day)
  GROUP BY `news_id`
  ORDER BY `count` DESC
  LIMIT 100

Ну и индексы по `like`.`date` и `like`.`news_id`, возможно комбинированный индекс, надо EXPLAIN смотреть.
Ответ написан
@Wol_fi
php, js, mysql, highload
SELECT x.* FROM 
(
SELECT n.id, count(*) AS count_like FROM news AS n 
LEFT JOIN `like` AS l ON n.id = l.news_id 
WHERE l.`date` > date_add(NOW(), INTERVAL -7 day) 
GROUP BY n.id
) AS x ORDER BY x.count_like DESC LIMIT 100;

попробуйте так.
индексы на news.id, like.news_id, likes.date
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы