Google bigquery 查询6小时后超时,如何优化?
我有两个表,Google bigquery 查询6小时后超时,如何优化?,google-bigquery,gis,cartesian-product,Google Bigquery,Gis,Cartesian Product,我有两个表,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 uni
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
这些形状表示车辆的行驶路线。对于每种形状,我们在单独的表格中计算了有害物质的排放量。目的是计算每平方网格的排放量,假设排放量沿路线均匀分布。为此,我们需要知道管线形状的哪个部分与每个网格单元相交
下面是计算该值的查询:
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执行:
-
空间联接是在
子句中具有谓词地理函数的两个表的联接 检查。我甚至将我的WHERE
重写为上面所示的等效“逗号”连接内部连接
-
当地理数据被持久化时,空间连接的性能会更好
检查。
和shape\u geography
都直接来自现有的表格square\u geography
-
BigQuery使用以下标准SQL谓词函数为内部联接和交叉联接运算符实现优化的空间联接:[……]
检查。只需一次ST_Intersects
调用,无其他条件ST_Intersect
- 空间连接未优化:用于左、右或完全外部连接;涉及反加入的案件;当空间谓词被否定时 检查。这些情况都不适用
- 避免产生比输入更多输出的联接 这个查询肯定会产生比输入更多的输出;这是它的本质,无法避免
-
当需要交叉联接时,请预先聚合数据
要避免与生成的输出多于输入的联接相关的性能问题,请执行以下操作:
- 使用GROUPBY子句预聚合数据
表中的每个形状都是唯一和不同的shapes
-
- 使用窗口功能。窗口函数通常比使用交叉联接更有效。有关详细信息,请参阅
如何在合理的时间内运行此查询?下面的注释格式肯定不适合,因此我必须将此作为答案发布 我对你的问题做了三个调整
- 正在使用连接。。。在上而不是交叉连接。。。在哪里
- 注释掉
计算平方部分
- 将目标表与
选项一起使用允许大结果
显然,取消注释
square\u部分
计算将增加插槽使用率-因此,您可能需要重新审视您的要求/期望我认为正方形
被颠倒了,导致几乎全地球多边形:
select st_area(square_geography), * from `open-transport-data.public.squares`
打印结果,如5.1E14
——这是一个完整的全局区域。所以任何一条线几乎都与所有的正方形相交。详见BigQuery单据:
您可以通过运行ST_GeogFromText(wkt,FALSE)
-来反转它们-它选择较小的多边形,忽略多边形方向,这相当快:
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
`open-transport-data.public.shapes`,
(select
square_key,
st_geogfromtext(st_astext(square_geography), FALSE) as square_geography,
from `open-transport-data.public.squares`) squares
WHERE
ST_INTERSECTS(shape_geography, square_geography)
你能提供这些表格的样本吗?我想复制it@rmesteves非常感谢。我已经授予
bigquery.dataViewer
访问alluser
,希望这就足够了。表的名称是开放式传输数据.public.shapes
和开放式传输数据.public.squares
。逗号是交叉连接
-这可能会破坏您的query@MartinWeitzmann当然是交叉连接。就像我说的,这是野兽的本性。谢谢你的彻底调查!6.6B输出行意味着我们得到了完整的笛卡尔积。。。那不是我的本意。明天我会仔细看看数据。是的,就是这样,非常感谢!我现在要对QGIS说一些严厉的话,因为这些正方形来自的CSV with WKT导出似乎包含右手多边形,即使WKT应该使用左手规则。
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
`open-transport-data.public.shapes`,
(select
square_key,
st_geogfromtext(st_astext(square_geography), FALSE) as square_geography,
from `open-transport-data.public.squares`) squares
WHERE
ST_INTERSECTS(shape_geography, square_geography)