Bigquery Shuffle失败并出现错误

时间:2014-04-22 23:22:48

标签: google-bigquery

我的查询如下:

SELECT 
ducc.*, dl.LOCATIONID, dl.LOCATIONNAME
FROM [table1] ducc
LEFT OUTER JOIN EACH [table2] dl
ON ducc.LOCATIONID = dl.LOCATIONID
WHERE ABS(ducc.LOCATIONID % 30) = 0

它给了我" Shuffle因错误而失败:一次洗牌不能超过3.00T。此查询中的一个shuffle分区超过了7.68G。可以在go / dremelfaq上找到解决此错误的策略。"

我认为它不能正确排序和改组,因为我从[table2]得到两列,因为排列的复杂性很高。

为此做任何解决方法?

2 个答案:

答案 0 :(得分:3)

有几种可能性:

  1. 加入爆炸。 table2中的位置ID是唯一的吗?如果没有,您可以创建一个NxM扩展,其中table1中的所有N个匹配字段与所有M个匹配字段和table2匹配,并在输出中创建的行数多于输入中的行数。
  2. 连接键的分布非常不平衡。也就是说,如果一个LOCATIONID占table1中的大部分行。有时这可能是预期的。有时,这是因为默认值。例如,如果table1有很多行,其中LOCATIONID未知,那么按惯例,使用0,这意味着大量数据被散列到同一位置。
  3. 这也可能只是起作用。如果您提供失败作业的作业ID,则其中一位BigQuery工程师可以查找问题并查看出现了什么问题。
  4. 请注意,对于这些问题,您正在进行的分区(ABS(ducc.LOCATIONID%30 = 0)不一定有用,因为满足此条件的值都将被散列到同一位置。

    你可以尝试一些事情:

    1. 如果您有连接爆炸,可以在连接右侧的子选择中执行GROUP EACH BY,这样您只能获得不同的值。例如:

      SELECT 
      ducc.*, dl.LOCATIONID, dl.LOCATIONNAME
      FROM [table1] ducc
      LEFT OUTER JOIN EACH 
          (SELECT LOCATIONID, MIN(LOCATIONNAME) as LOCATIONNAME 
           FROM [table2] 
           GROUP EACH BY LOCATIONID)  dl
      ON ducc.LOCATIONID = dl.LOCATIONID
      WHERE ABS(ducc.LOCATIONID % 30) = 0
      
    2. 删除EACH限定符。这意味着您不必进行随机播放。这只适用于table2足够小的情况。但是,您可以将过滤应用于该表,这可能会有所帮助,如:

      SELECT 
      ducc.*, dl.LOCATIONID, dl.LOCATIONNAME
      FROM [table1] ducc
      LEFT OUTER JOIN 
          (SELECT LOCATIONID, LOCATIONNAME
           FROM [table2] 
           WHERE ABS(ducc.LOCATIONID % 30) = 0)  dl
      ON ducc.LOCATIONID = dl.LOCATIONID
      
    3. 如果问题是由于匹配的虚拟值而导致其中一个散列桶太大,您当然可以尝试将其过滤掉。如果它是具有大部分匹配的合法值,则可以将查询分解为多个部分,将“太多匹配”的部分首先作为JOIN而不是每个匹配,将其他部分作为单独的查询每次加入。您可以通过指定要将第一个查询的结果附加到第二个查询来将结果连接在一起。

答案 1 :(得分:1)

感谢乔丹的洞察力

我猜案例2是导致问题的原因

"连接键的分布非常不平衡。也就是说,如果一个LOCATIONID占table1中的大部分行。有时这可能是预期的。有时,这是因为默认值。例如,如果table1有很多行,其中LOCATIONID未知,那么按惯例,使用0,这意味着大量数据被散列到同一位置。"

table1.LOCATIONID中的大多数值都是NULL。所以即使我拥有所有table2.LOCATIONID也是唯一的,但它失败了。

一旦我加入了在table1和table2上都有99%不同值的列,那么它就像魅力一样