MySql Присоединяйтесь медленно с SUM () результатов

0

кто-нибудь знает более эффективный способ выполнения этого запроса?

SELECT SQL_CALC_FOUND_ROWS p.*, IFNULL(SUM(v.visits),0) AS visits,
FROM posts AS p 

LEFT JOIN visits_day v ON v.post_id=p.post_id 

GROUP BY post_id 
ORDER BY post_id DESC LIMIT 20 OFFSET 0

Таблица visit_day имеет одну запись в день, за пользователя, за сообщение. С ростом таблицы этот запрос очень медленный.

Я не могу добавить столбец с общим количеством посещений, потому что мне нужно перечислять сообщения больше посещений в день или неделю и т.д.

Кто-нибудь знает это решение?

Спасибо

CREATE TABLE 'visits_day' (
 'id' int(11) NOT NULL AUTO_INCREMENT,
 'post_id' int(11) NOT NULL,
 'user_id' int(11) NOT NULL,
 'day' date NOT NULL,
 'visits' int(11) NOT NULL,
 PRIMARY KEY ('id')
) ENGINE=InnoDB AUTO_INCREMENT=52302 DEFAULT CHARSET=utf8

CREATE TABLE 'posts' (
 'post_id' int(11) NOT NULL AUTO_INCREMENT,
 'link' varchar(300) NOT NULL,
 'date' datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
 'title' varchar(500) NOT NULL,
 'img' varchar(300) NOT NULL,
 PRIMARY KEY ('post_id')
) ENGINE=InnoDB AUTO_INCREMENT=1027 DEFAULT CHARSET=utf8
Теги:
performance
join
left-join
subquery

1 ответ

0

С SQL_CALC_FOUND_ROWS запрос должен оценивать все, просто не доставлять все строки. Избавиться от этого должно быть полезно.

Чтобы на самом деле коснуться только 20 строк, нам нужно пройти через WHERE, GROUP BY и ORDER BY с помощью одного индекса. В противном случае нам, возможно, придется коснуться всех строк, отсортировать их, а затем доставить 20. Очевидным индексом является (post_id); Я подозреваю, что уже проиндексирован как PRIMARY KEY(post_id)? (Это поможет, если вы предоставите SHOW CREATE TABLE при задании вопросов.)

Другой способ сделать соединение и получить нужный результат от нуля, заключается в следующем. Обратите внимание, что это исключает необходимость в GROUP BY.

SELECT p.*,
       IFNULL( ( SELECT SUM(v.visits)
                   FROM visits_day
                   WHERE post_id = p.post_id
               ),
            0) AS visits
    FROM posts AS p 
    ORDER BY post_id DESC
    LIMIT 20 OFFSET 0

Если вам действительно нужен счет, тогда рассмотрите SELECT COUNT(*) FROM posts.

ON v.post_id=p.post_id в вашем запросе, а WHERE post_id = p.post_id для INDEX(post_id) на visits_day. Это значительно ускорит оба варианта.

  • 0
    Спасибо, Рик, это была хорошая идея. Но проблема сохраняется, когда мне нужно отфильтровать посты за посещение, используя порядок по. знак равно
  • 0
    @FelipeB. - а? Я думал, что моя версия даст те же результаты.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню