【发布时间】:2017-06-02 11:37:26
【问题描述】:
我有两张桌子:
用户(ID、姓名)
user_activities(id、user_id、activity_id、created_at)
user_activities 表非常大,有超过 3 亿行。
我正在尝试检测哪些用户在给定日期范围内进行了任何活动。换句话说,用户表上的行,其中一个连接行存在于 user_activities 表上某个 created_at 范围之间。
我可以使用 INNER JOIN、GROUP BY 和 WHERE 子句来做到这一点,但查询会运行很长时间,因为我相信它会在我的日期范围内命中所有 user_activities 行。
我真的不在乎“有多少”活动,只要他们有超过零个。所以我正在分组以获得计数(例如 210 个活动),而实际上我可以在找到 1 个后停止。
有没有比将所有 user_activity 行分组来计数更有效的方法?
有关信息,这是当前查询,它工作正常但需要很长时间:
SELECT u.id, u.name, COUNT(ua.id) AS activity_count
FROM users u
INNER JOIN user_activity ua ON u.id=ua.user_id
WHERE ua.created_at > '2017-01-01' AND ua.created_at < '2017-03-01'
GROUP BY u.id
HAVING activity_count > 0;
提前致谢!
【问题讨论】:
-
这里不需要 HAVING,没有活动的用户不会被包括在内。 (即 activity_count 将始终大于 0。)
-
那么我也可以删除 COUNT(ua.id) 吗?
-
您是否需要计算每个用户的活动,还是知道用户处于活动状态(即在日期范围内至少有一项活动)就足够了?
-
是的,不需要 - 只要您只是想知道是否有任何活动。
-
至少存在 1 个活动,我不需要计算总共有多少。我认为 Gordon 在下面的第二个答案是进行此存在检查,所以我会尝试。