首页 > 解决方案 > 6小时后查询超时,如何优化?

问题描述

我有两个表,shapes并且squares,我基于GEOGRAHPY列的交叉点加入。

shapes表包含车辆的行驶路线:

shape_key        STRING            identifier for the shape
shape_lines      ARRAY<GEOGRAPHY>  consecutive line segments making up the shape
shape_geography  GEOGRAPHY         the union of all shape_lines
shape_length_km  FLOAT64           length of the shape in kilometers

Rows: 65k
Size: 718 MB

我们保持shape_lines分离,ARRAY因为形状有时会在自身上重复,并且我们希望将这些线段保持分离而不是重复数据删除

squares表包含一个 1×1 平方千米的网格:

square_key        INT64      identifier of the grid square
square_geography  GEOGRAPHY  four-cornered polygon describing the grid square

Rows: 102k
Size: 15 MB

这些形状代表车辆的行驶路线。对于每种形状,我们在单独的表格中计算了有害物质的排放量。目的是计算每个方格的排放量,假设它们沿路线均匀分布。为此,我们需要知道路线形状的哪一部分与每个网格单元相交。

这是计算它的查询:

SELECT
  shape_key,
  square_key,
  SAFE_DIVIDE(
      (
        SELECT SUM(ST_LENGTH(ST_INTERSECTION(line, square_geography))) / 1000
        FROM UNNEST(shape_lines) AS line
      ),
      shape_length_km)
    AS square_portion
FROM
  shapes,
  squares
WHERE
  ST_INTERSECTS(shape_geography, square_geography)

遗憾的是,此查询在 6 小时后超时,而不是产生有用的结果。

在最坏的情况下,查询可以产生 66 亿行,但实际上不会发生这种情况。我估计每个形状通常与 50 个网格正方形相交,因此输出应该是大约 65k * 50 = 3.3M 行;BigQuery 不应该处理任何事情。

我考虑了BigQuery 执行的地理连接优化:

所以我认为 BigQuery 应该能够使用它使用的任何空间索引数据结构来优化这个连接。

我还考虑了有关交叉连接的建议

我怀疑 BigQuery 根据输入行数分配资源,而不是根据中间表或输出的大小。这可以解释我所看到的病态行为。

我怎样才能使这个查询在合理的时间内运行?

标签: google-bigquerygiscartesian-product

解决方案


下面绝对不适合评论格式,所以我必须将其发布为答案...

我对您的查询进行了三项调整

  • 使用 JOIN ... ON 而不是 CROSS JOIN ... WHERE
  • 注释掉square_portion计算
  • 使用带有Allow Large Results选项 的目标表

即使您期望输出只有 330 万行 - 实际上它大约是 6.6 B ( 6,591,549,944) 行 - 您可以在下面看到我的实验结果

在此处输入图像描述

请注意有关计费层级的警告-因此,如果可用,您最好使用预留
显然,取消注释square_portion计算会增加插槽使用率-因此,您可能需要重新审视您的要求/期望


推荐阅读