我在这里有这个SQL查询,它抓住了5个最新的新闻帖子。我想这样做它也可以在同一个查询中抓取总喜欢和总新闻评论。但是当我处理大量数据时,我所做的查询似乎有点慢,所以我试图看看我是否能找到更好的解决方案。它在下面:
SELECT *,
`id` as `newscode`,
(SELECT COUNT(*) FROM `likes` WHERE `type`="newspost" AND `code`=`newscode`) as `total_likes`,
(SELECT COUNT(*) FROM `news_comments` WHERE `post_id`=`newscode`) as `total_comments`
FROM `news` ORDER BY `id` DESC LIMIT 5
这也是一个SQLFiddle:http://sqlfiddle.com/#!2/d3ecbf/1
答案 0 :(得分:1)
我建议在total_likes
表中添加total_comments
和news
字段,只要添加或删除了喜欢和/或评论,它就会递增/递减。
您的likes
和news_comments
表格仅用于历史目的。
每次加载页面时都不应执行这种繁重的计数,因为这样会完全浪费资源。
答案 1 :(得分:0)
首先检查列 id , post_id 和类型,代码的索引。
答案 2 :(得分:0)
我认为这是T-SQL,因为这是我最熟悉的。
首先,我会检查索引。如果那看起来不错,那我就检查声明。查看您的查询地图,了解它如何填充您的结果。
SQL向后工作,因此它从您上一个AND
语句开始,然后从那里开始。它会将它们全部按代码分组,然后输入,最后给你一个计数。
现在,无论日期如何,您都会使用某些代码抓取所有内容。当你说你想要最新版本时,我假设某处有一个日期栏。
为了加快速度,请在AND
添加另一个WHERE
并说明日期。无论是过去24小时,还是上周,无论如何。
答案 3 :(得分:0)
你可以使用连接重写它,MySQL已经知道子查询的问题,特别是在处理大型数据集时:
SELECT n.*,
`id` as `newscode`,
COALESCE(l.TotalLikes, 0) AS `total_likes`,
COALESCE(c.TotalComments, 0) AS `total_comments`
FROM `news` n
LEFT JOIN
( SELECT Code, COUNT(*) AS TotalLikes
FROM `likes`
WHERE `type` = "newspost"
GROUP BY Code
) AS l
ON l.`code` = n.`id`
LEFT JOIN
( SELECT post_id, COUNT(*) AS TotalComments
FROM `news_comments`
GROUP BY post_id
) AS c
ON c.`post_id` = n.`id`
ORDER BY n.`id` DESC LIMIT 5;
原因是当你使用上面的连接时,MySQL会在第一次需要时实现子查询的结果,例如在这个查询开始时,mySQL会把结果放在:
SELECT post_id, COUNT(*) AS TotalComments
FROM `news_comments`
GROUP BY post_id
进入内存表并使用hash post_id进行更快速的查找。然后,对于news
中的每一行,只需从此散列表中查找TotalComments
,当您使用相关子查询时,它将为news
中的每一行执行一次查询, news
很大会导致大量执行。如果初始结果集很小,您可能看不到性能优势,而且可能更糟。
SQL小提琴上的示例
最后,您可能希望为news_comments
和likes
中的相关字段编制索引。对于此特定查询,我认为以下索引将有所帮助:
CREATE INDEX IX_Likes_Code_Type ON Likes (Code, Type);
CREATE INDEX IX_newcomments_post_id ON news_comments (post_id);
虽然您可能需要将第一个索引拆分为两个:
CREATE INDEX IX_Likes_Code ON Likes (Code);
CREATE INDEX IX_Likes_Type ON Likes (Type);