2012-07-08 70 views
0

我有一个评论近200万行的表。我们每天收到约500条新评论。每条评论都被分配到一个特定的ID。我想根据具体ID获取最受欢迎的“讨论”。如何抓住表中最受欢迎的行?

我在ID列上有一个索引。

什么是最佳实践?我是否按这个ID进行分组,然后根据评论最多的ID进行排序?这对于这种尺寸的桌子最有效吗?

+0

什么被视为“*最受欢迎*”?评论前10位的讨论最多?前50名?您是否缩小了特定日期之后的讨论范围? – 2012-07-08 04:30:39

+0

最佳做法是保持简单并编写普通的SELECT查询,如Zane的答案。 – 2012-07-08 04:40:48

回答

4

我只是按这个ID进行分组,然后根据评论最多的ID进行排序?

这很简单,我会怎么做。就让我们假设你要检索的前50名:如果您的用户在应用程序相当频繁执行这个查询

SELECT id 
FROM comments 
GROUP BY id 
ORDER BY COUNT(1) DESC 
LIMIT 50 

,你就发现它没有运行非常快,你想,一个办法你可以优化它是将上述查询的结果存储在一个单独的表(topdiscussions)中,并且可能有一个脚本或cron间隔运行,每五分钟左右更新一次该表。

在您的应用程序

然后,只需要您的用户从topdiscussions表中选择,使他们只需要从行,而不是选择。

这样做的缺点当然是选择不再是实时的,而是最多五分钟不同步,或者经常要更新表格。您实际需要的实时性取决于系统的要求。

编辑:根据您对此答案的评论,我更了解您的架构和要求。以下查询检索过去一天内最活跃的讨论:

SELECT a.id, etc... 
FROM discussions a 
INNER JOIN comments b ON 
    a.id = b.discussion_id AND 
    b.date_posted > NOW() - INTERVAL 1 DAY 
GROUP BY a.id 
ORDER BY COUNT(1) DESC 
LIMIT 50 

我不知道您的字段名称,但这是总体思路。

+0

你依靠不合逻辑和非标准的行为。更好的数据库会给你一个类似于['Column'xyz'在选择列表中无效的错误,因为它不包含在聚合函数或GROUP BY子句中。](http://weblogs.sqlteam.com /jeffs/archive/2007/07/20/but-why-must-that-c​​olumn-be-contained-in-an-aggregate.aspx)。更合适的解决方案是只选择讨论标识和评论数量,然后通过连接自己获取讨论/评论。 – DCoder 2012-07-08 04:59:49

+1

@DCoder,我按照自己的方式编写的两个原因:** 1)**我不知道OP的DB结构或他/她需要选择的列。也许'id'链接到另一个名为'discuss'的表,在这里你需要一个连接来获得关于讨论的信息/或者评论表是非规范化的,并且还包含讨论标题,user_id等。** 2) **这明确标记为允许这一点的MySQL。我只想根据所提供的信息展示最简单的例子。 – 2012-07-08 05:06:47

+0

是的,该ID与另一个表相关联,您是正确的。而且,我还需要按日期。所以,如果我想说的话,给我昨天围绕身份证的前50名讨论。 – Mike 2012-07-08 15:27:41

0

如果我理解您的问题,则ID表示讨论附有评论。所以,首先你需要一些最流行的概念。
1)由ID计数评论和设置一个名为“增量”列0

2)初始化“注释总”表定期

2.1)计数由ID的评论

2.2)从新计数中减去旧计数并将该值存储到增量列中。

2.3)用新的计数替换注释的数量。

3)选择10个'最热门'的讨论,从评论总数中选择10行,按降序排列。

现在其余的都是微不足道的。这只是其讨论ID与您在步骤3中找到的讨论ID相匹配的评论。