TL; DR: Verwenden Sie GROUP EACH BY
in der inneren Abfrage.
Die innere Abfrage
Select a, max(x) as b from Tbl1 group by a
ist nicht parallelisierbare. Sie können Teilergebnisse parallel berechnen, aber um den globalen Wert max(x)
für jeden Wert von a
'zu kennen, müssen Sie dies nur an einer Stelle ausführen lassen. Wenn Sie JOIN EACH
in der äußeren Abfrage verwenden, weisen Sie die Abfrage-Engine an, die Sie parallel zu der JOIN
-Ausführung benötigen. Da Sie jedoch keine parallelisierbare Quelle haben, schlägt die Abfrage fehl.
Es gibt zwei Möglichkeiten, dies zu beheben: Die erste besteht darin, eine explizit parallele Version der inneren Abfrage zu verwenden - verwenden Sie einfach GROUP EACH BY
anstelle von GROUP BY
. Dies kann parallel ausgeführt werden, da der erste Schritt darin besteht, die zugrunde liegende Tabelle nach dem Feld a
zu sortieren, sodass Sie das globale Maximum pro a
-Feld in einem parallelen Worker berechnen können. Wenn die innere Abfrage parallelisiert werden kann, kann die äußere Abfrage auch parallel ausgeführt werden. Dies würde wie folgt aussehen:
Select Table1.a,Table1.b,Table2.c
From
(Select a, max(x) as b
from Tbl1
group EACH by a -- note the EACH keyword here
) as Table1
LEFT JOIN EACH Table2
ON
Join Condition
Die zweite Option ist JOIN
statt JOIN EACH
auf der äußeren Abfrage zu verwenden. Abhängig von der Größe von Tabelle2 kann dies zu Größenbeschränkungen führen (da für einen Nicht-Jeder-Join die Tabelle auf der rechten Seite "klein" sein muss).
Dies ist zwar suboptimal; Sie müssen verstehen, wie die Abfrage-Engine funktioniert, damit Ihre Abfragen ausgeführt werden. Allerdings arbeiten wir (in den Bigquery- und Dremel-Teams) hart daran, Anfragen so zu gestalten, dass sie "nur funktionieren", damit Sie sich nicht mit dieser Art von Problem befassen müssen. Wir machen einige Fortschritte, einige dieser Arten von Fehlern wurden in den letzten Monaten entfernt (zum Beispiel wäre ein innerer Join auch bis vor kurzem gescheitert), aber wir haben noch einen Weg zu gehen.
Vielen Dank, dass Sie uns darauf aufmerksam gemacht haben. Ich habe einen internen Fehler eingereicht, damit wir in Zukunft besser arbeiten können.