每个可并行化

时间:2014-04-24 07:40:41

标签: google-bigquery

我一次又一次地遇到这个障碍......

JOIN EACH and GROUP EACH BY clauses can't be used on the output of window functions

是否有最佳实践或建议如何使用窗口函数(Over())以及无法在单个节点上处理的非常大的数据集?

对我的数据进行分段并使用不同的过滤器运行相同的查询可以正常工作,但是它非常有限,需要花费大量时间(和人工)并且成本高昂(在同一数据集上运行相同的查询30次而不是一次)。 / p>

参考Jeremy的回答...... 它更好,但仍然无法正常工作。 如果我采用原始查询样本:

select title,count (case when contributor_id<>LeadContributor then 1 else null end) as different,
count (case when contributor_id=LeadContributor then 1 else null end) as same,
count(*) as total
from
(
SELECT title,contributor_id,lead(contributor_id)over(partition by title order by timestamp) as LeadContributor  
FROM [publicdata:samples.wikipedia]
where regexp_match(title,r'^[A,B]')=true
)
group by title

现在有效...... 但

select title,count (case when contributor_id<>LeadContributor then 1 else null end) as different,
count (case when contributor_id=LeadContributor then 1 else null end) as same,
count(*) as total
from
(
SELECT title,contributor_id,lead(contributor_id)over(partition by title order by timestamp) as LeadContributor  
FROM [publicdata:samples.wikipedia]
where regexp_match(title,r'^[A-Z]')=true
)
group each by title

再次提供资源超出错误...

2 个答案:

答案 0 :(得分:1)

现在可以根据OVER中给出的PARTITION BY子句以分布式方式执行窗口函数。如果您使用窗口函数提供PARTITION BY,则将并行处理您的数据,类似于处理JOIN EACH和GROUP EACH BY的方式。

此外,您可以在JOIN EACH或GROUP EACH BY的输出上使用PARTITION BY,而无需序列化执行。使用与JOIN EACH或GROUP EACH BY相同的PARTITION BY键特别有效,因为在连接/聚合和窗口函数执行之间不需要重新调整数据。

答案 1 :(得分:0)

更新:请注意Jeremy的评论并带来好消息。

OVER()函数总是需要在整个数据集上运行作为执行的最后一步(它们甚至在LIMIT子句之后运行)。除非可以与PARTITION子句并行化,否则一切都需要适合最后一个VM。

当我发现这种类型的错误时,我尝试在早期的步骤中尽可能多地过滤数据。

例如,此查询不会运行:

SELECT Year, Actor1Name, Actor2Name, c FROM (
 SELECT Actor1Name, Actor2Name, Year, COUNT(*) c, RANK() OVER(PARTITION BY YEAR ORDER BY c DESC) rank
 FROM 
 (SELECT Actor1Name, Actor2Name,  Year FROM [gdelt-bq:full.events] WHERE Actor1Name < Actor2Name),
 (SELECT Actor2Name Actor1Name, Actor1Name Actor2Name, Year FROM [gdelt-bq:full.events] WHERE Actor1Name > Actor2Name),
 WHERE Actor1Name IS NOT null
 AND Actor2Name IS NOT null
 GROUP EACH BY 1, 2, 3
)
WHERE rank=1
ORDER BY Year

但是我可以使用早期的过滤器轻松修复它,在这种情况下添加“HAVING c&gt; 100”:

SELECT Year, Actor1Name, Actor2Name, c FROM (
 SELECT Actor1Name, Actor2Name, Year, COUNT(*) c, RANK() OVER(PARTITION BY YEAR ORDER BY c DESC) rank
 FROM 
 (SELECT Actor1Name, Actor2Name,  Year FROM [gdelt-bq:full.events] WHERE Actor1Name < Actor2Name),
 (SELECT Actor2Name Actor1Name, Actor1Name Actor2Name, Year FROM [gdelt-bq:full.events] WHERE Actor1Name > Actor2Name),
 WHERE Actor1Name IS NOT null
 AND Actor2Name IS NOT null
 GROUP EACH BY 1, 2, 3
 HAVING c > 100
)
WHERE rank=1
ORDER BY Year

所以这里发生了什么:在应用RANK()OVER()之前,我正在摆脱许多组合,这些组合在我寻找顶级组合时无关紧要(因为我已经过滤了所有内容)计数小于100)。

为了提供更具体的答案,如果您可以提供查询和样本数据进行审核,那么总是更好。

相关问题