1

有没有更有效的方法从每个组中获取前 X 个结果?

您可以忽略查询中未使用的 sqlfiddle 中的任何字段。

查询:

SET @num := 0, @item_id := '';
SELECT `item_id`, `user_id`, total_hoarded FROM (
        SELECT `item_id`, `user_id`, total_hoarded,
                @num := IF(@item_id = x.`item_id`, @num + 1, 1) AS ROW_NUMBER,
                @item_id := x.`item_id` AS dummy
        FROM (
                SELECT `item_id`, `user_id`, COUNT(*) AS total_hoarded
                FROM `player_items`
                GROUP BY `item_id`, `user_id`
                ORDER BY `item_id`, total_hoarded DESC
        ) AS x
) AS y WHERE y.ROW_NUMBER <= 10;");

演示:http ://sqlfiddle.com/#!2/75bc7/1

查询说明

(从最嵌套的查询开始)它通过 item_id 和 user_id 抓取并分组所有行,以便我们可以做一些聚合函数来计算每个用户有多少项目。

下一级然后将 row_number 附加到每一行,以便最终查询可以简单地获取小于 X 的所有行(在这种情况下,每个分组的前 10 个用户)。

SQLFiddle 在样本的大小方面受到限制,因此它只显示两个项目和少数用户的数据。不足以完全进入前 10 名,但足以说明我在做什么。

选项(我正在考虑)

  • 保持原样查询。
  • 做一个标准的查询分组并通过 PHP 循环获取前 10 名
  • 其他?(其他的还没想好)

备注

我意识到我可能没有提供足够的细节,所以让我知道你需要什么。我只是在寻找一种通用的方法来解决这个问题。上面的查询在 30mill 行的表上运行大约需要 5 分钟。不过这没什么大不了的,因为查询每小时只运行一次。

将查询分成更小的部分可能会运行得更快,但表会被写入很多内容,因此查询往往会被锁定。

4

0 回答 0