mysql join slow with sum()of results

cwtwac6a  于 2021-06-24  发布在  Mysql
关注(0)|答案(1)|浏览(239)

有人知道执行这个查询的更有效的方法吗?

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

visits\u 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
gdx19jrr

gdx19jrr1#

SQL_CALC_FOUND_ROWS ,查询必须计算所有内容,而不是传递所有行。摆脱这些应该是有益的。
要真正接触到20排,我们需要通过 WHERE , GROUP BY 以及 ORDER BY 只有一个索引。否则,我们可能需要触摸所有行,对它们进行排序,然后交付20行。最明显的指标是 (post_id) ; 我怀疑它已经被索引为 PRIMARY KEY(post_id) ? (如果你能提供 SHOW CREATE TABLE 问问题时。)
另一种进行连接并获得所需结果0的方法如下。请注意,它消除了 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 . 这将大大加快这两种变体的速度。

相关问题