4

有什么想法可以让这个查询在 Google BigQuery 上返回结果吗?我收到资源超出错误...数据集中大约有 2B 行。我正在尝试获取每个 user_id 出现最多的艺术家 ID。

select user_id, artist, count(*) as count
from [legacy20130831.merged_data] as d
group each by user_id, artist
order by user_id ASC, count DESC
4

1 回答 1

7

对公共数据的等效查询,会引发相同的错误:

SELECT actor, repository_name, count(*) AS count
FROM [githubarchive:github.timeline] AS d
GROUP EACH BY actor, repository_name
ORDER BY actor, count desc

与相同的查询进行比较,加上要返回的结果的限制。这个有效(对我来说是 14 秒):

SELECT actor, repository_name, count(*) as count
FROM [githubarchive:github.timeline] as d
GROUP EACH BY actor, repository_name
ORDER BY actor, count desc
LIMIT 100

您可以通过一小部分 user_ids 来代替使用 LIMIT。就我而言,1/3 有效:

SELECT actor, repository_name, count(*) as count
FROM [githubarchive:github.timeline] as d
WHERE ABS(HASH(actor) % 3)  = 0
GROUP EACH BY actor, repository_name

但是您真正想要的是“获取每个 user_id 出现最多的艺术家 ID”。让我们更进一步,得到:

SELECT actor, repository_name, count FROM (
  SELECT actor, repository_name, count, ROW_NUMBER() OVER (PARTITION BY actor ORDER BY count DESC) rank FROM (
    SELECT actor, repository_name, count(*) as count
    FROM [githubarchive:github.timeline] as d
    WHERE ABS(HASH(actor) % 10) = 0
    GROUP EACH BY actor, repository_name
))
WHERE rank=1

请注意,这次我使用了 %10,因为它可以更快地获得结果。但是您可能想知道“我想通过一个查询而不是 10 个查询来获得我的结果”。

为此,您可以做两件事:

  • 合并分区表(FROM 表达式中的逗号执行联合,而不是 BigQuery 中的联接)。
  • 如果您仍然超出资源,您可能需要具体化该表。运行原始查询并将结果保存到新表中。在该表上运行 RANK() 算法,而不是在内存中的 GROUP 上运行。

如果您愿意与我分享您的数据集,我可以提供针对数据集的建议(很大程度上取决于基数)。

于 2013-09-03T20:38:01.473 回答