我有一个包含用户记录的表,我希望每user_id
个记录5个。我不关心任何秩序。我可以这样做,每个用户获得1条记录:
SELECT * FROM记录GROUP BY user_id
我也可以用user variables做一些事情来获得前N个记录。但是,我的数据库非常大,并且使用用户变量的查询无法有效地使用user_id
列上的索引,因为它必须在每个组中进行排序。我根本不关心订单,所以我不应该触摸那些不相关的记录。由于我只想要5个,每个用户有200-400个记录,这是一个很大的性能影响。
有没有办法有效地编写此查询?
这个问题不与询问如何获得前N个记录相同,因为我不关心排序,我相信删除该限制应该允许有效的重写。如果不是这样,请解释原因。我在标题中澄清了这一点。
答案 0 :(得分:2)
尝试使用以下查询。 子查询将根据 Order By 子句中提到的列对行进行编号。在外部查询中,您可以给出过滤条件。
SET @rowNum = NULL, @rowVal = NULL;
SELECT * FROM (
SELECT
*,
@rowNum := IF(@rowVal = userid, @rowNum + 1, 1) AS Rno,
@rowVal := userid AS Dummy
FROM Yourtable
ORDER BY [user_id]
) AS t
WHERE Rno <= 5
答案 1 :(得分:0)
您可以使用视图和分区来解决此问题:
创建查询核心表的视图(添加一个RowId列,计算每个user_id的记录数):
SELECT *, ROW_NUMBER() OVER(PARTITION BY User_id) AS RowID
FROM Records
让我们假设你调用上面的视图^“Recordsvw ”
这很简单,现在每个user_id只需要5条记录查询您在上面创建的视图,如下所示:
SELECT *
FROM Recordsvw
WHERE ROwID <= 5