是否有更快的方法从表中选择不同的用户数?也许使用row_number,分区或交叉应用?
我现在想不起来。
示例:
Table UsageLog
UserId Date StoreNumber
Alice 200901 342
Alice 200902 333
Alice 200902 112
Bob 200901 112
Bob 200902 345
Charlie 200903 322
这是我当前的查询:
select count(distinct userID), date
from
UsageLog
where
date between 200901 and 200902
group by date
我的实际表有数百万行,所有列实际上都是整数。
有更快的方法来获取用户列表吗?
修改:
我已经在所有单独的列上都有非聚簇索引。出于某种原因,执行计划显示我仍在进行表扫描。我想我应该在Date上创建一个聚簇索引。我会看看它是如何运作的......
答案 0 :(得分:3)
总的来说,我没有找到比你那里更快的方法,COUNT(DISTINCT UserId)是一个非常基本的查询。
这里最重要的是确保您在表上有一个索引,该索引适用于“日期”列和UserId列
答案 1 :(得分:2)
Date和UserId上的复合索引应该有很多帮助
答案 2 :(得分:2)
SELECT DISTINCT()是要走的路。问题是您正在点击date
index tipping point,因此您的计划将用于聚集索引扫描。请参阅Kimberley L. Tripp文章的链接,了解“引爆点”是什么。
您需要覆盖索引:
CREATE INDEX idx_UsageLog_date_user_id ON UsageLog(date) INCLUDE (userID);
聚集索引也可以使用,但也有其他副作用。如果date
上的聚簇索引与其他数据访问模式一致,则优于我建议的覆盖索引。
<强>更新强>
您在(userID, date)
上尝试的逆序索引也有效,将搜索每个用户ID。实际上比(date, userID)
或(date) INCLUDE (userID)
更好,因为它返回预先排序的userID,因此DISTINCT不会引入额外的排序。
我仍然建议查看我发布的链接,了解为什么'每个列的索引'没有帮助。
答案 3 :(得分:1)
使用GROUP BY
并确保您在UserId
列
答案 4 :(得分:1)
日期和用户ID上的一个索引:执行计划显示索引搜索,但随后执行排序以执行非常慢的。
UserID和Date上的一个索引:执行计划显示索引扫描和两个计算,这导致我运行的所有方案的成本更低。
仅使用Date或仅带有索引的UserID的其他方案比前一个更昂贵。
答案 5 :(得分:0)
例如:
select count(userID), userID
from UsageLog
where date between 200901 and 200902
Group by userID
然后对两者做一个解释计划来比较性能。