在两列上使用 COUNT 和 GROUP BY 的 SQL 查询非常慢

Posted

技术标签:

【中文标题】在两列上使用 COUNT 和 GROUP BY 的 SQL 查询非常慢【英文标题】:Terribly slow SQL query with COUNT and GROUP BY on two columns 【发布时间】:2010-02-20 17:21:02 【问题描述】:

我正在归档这个网络论坛,它通常每周会被清除一次。所以我在屏幕上抓取它,并将其存储到我的数据库(PostgreSQL)中。

我还对数据进行了一些分析,提供了一些图表供用户欣赏,例如一天中什么时间论坛最活跃等等。

所以我有一个帖子表,如下所示:

   Column   |            Type
------------+------------------------------
 id         | integer
 body       | text
 created_at | timestamp without time zone
 topic_id   | integer
 user_name  | text
 user_id    | integer

我现在想为我的前 10 名小海报表中的每个用户计算帖子数。

我想出了这个:

SELECT user_id, user_name, count(*)
FROM posts
GROUP BY user_id, user_name
ORDER BY count DESC LIMIT 10

结果非常缓慢。 9 秒,此时帖子表中只有大约 300 000 行。

如果我只在一个列上分组,只需要半秒钟,但我需要两个。

我对关系数据库和 SQL 比较陌生,所以我不太确定这是否正确,或者我做错了什么?

【问题讨论】:

【参考方案1】:

可能只有一个用户具有特定 ID,因此 max(user_name) 应该等于 user_name。然后您可以在单个列上进行分组,您的帖子表明该列工作得更快:

SELECT user_id, max(user_name), count(*)
FROM posts
GROUP BY user_id

【讨论】:

+1 是的,这就是这样做的方法:)。在 sql 规范 1999 及更高版本中,实际上允许在 SELECT 列表中列出未出现在 GROUP BY 列表中的未聚合列,只要这些列在功能上依赖于 GROUP BY 列表.无耻塞:rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html【参考方案2】:

也可以使用 count > 0 所以你只返回 true

【讨论】:

以上是关于在两列上使用 COUNT 和 GROUP BY 的 SQL 查询非常慢的主要内容,如果未能解决你的问题,请参考以下文章

在 JOIN 中没有同时在两列上使用杜松子酒

在两列上创建索引以检查日期是不是介于这两个列之间

MySQL在两列上左连接

如何使用 UCanAccess 在两列上创建具有唯一约束的表?

在两列上检查唯一性的有效方法?

SQLalchemy:在两列上连接一个表