如何提高 BigQuery 中 ST_INTERSECT 的性能?

问题描述 投票:0回答:2

我有两张表,一张有 166M 地址点,一张有 170,000 个区域多边形。我想通过多边形与点相交,以获得一个包含地址 id 和地址所在辖区的辖区 id 的表。为了避免与州边界重叠的辖区出现问题(因为这是各个州数据集的合并数据集) ),我添加了一个条件,即每个文件中的状态相同。

为了提高性能,两个输入表均已按其各自的几何字段进行聚类,使用内部联接,并且输入表被具体化为表(根据有关使用空间联接的文档)。但是,该过程在完成之前就超时了。

为了排除故障,我确保辖区多边形具有预期的方向(这是这篇文章中的问题),并且我还查看了有关优化查询

的 BigQuery 文档

我尝试的第一件事是标准内部联接:

SELECT
    addr.id_address,
    prec.id_precinct,
    prec.geom  
FROM precincts AS prec
INNER JOIN addresses AS addr  
    ON prec.geo_state = addr.geo_state
        AND ST_INTERSECTS(addr.geom, prec.geom)

我也尝试过使用窗口函数:

SELECT *
FROM (
    SELECT
        addr.id_address,
        prec.id_precinct,
        prec.geom,
        ROW_NUMBER() OVER(PARTITION BY addr.geo_state) AS rn
    FROM addresses AS addr
    INNER JOIN precincts AS prec
        ON prec.geo_state = addr.geo_state
            AND ST_INTERSECTS(addr.geom, prec.geom)
) AS ranked
WHERE rn = 1

在这两种情况下,它都会在完成之前超时。非常感谢有关如何优化此查询的任何帮助。请注意,我使用

dbt
来运行此程序,并且我将超时设置为 1800 秒(不过,在 BigQuery UI 中运行它时也会超时)。

sql performance google-bigquery geospatial
2个回答
2
投票

TL;DR:如果删除状态相等条件

prec.geo_state = addr.geo_state
,查询运行速度是否足够快?如果是,解决方案是将其删除并作为单独的查询单独过滤,或者将其变成
=
两侧都依赖于左右连接子级的内容,例如

CONCAT(prec.geo_state, ".",  addr.geo_state) = CONCAT(addr.geo_state, ".", prec.geo_state)

说明:BigQuery 尚不支持不同类型 JOIN 条件的高效混合。如果它在单个连接中同时看到相等条件和地理空间条件,则它“更喜欢”相等连接,将地理空间谓词作为常规过滤条件执行,而不是构建和使用地理空间索引。

这就是为什么这个技巧通常会提高性能:它“隐藏”相等条件,使 BigQuery 使用地理空间连接,然后才检查现在复杂的相等条件。当然,只有在没有状态相等谓词的查询运行得相当快的情况下它才有效。


1
投票

Michael,我已经阅读了这篇文章,这篇文章希望对如何应用它有一些澄清。我有这个

SELECT columns
FROM a
JOIN b
ON a.county_fips IN UNNEST(b.county_fips_list) 
   AND ST_INTERSECTS(a.geometry, b.geopoint)
WHERE poi.client_id IN UNNEST(partner_list)

county_fips 是字符串类型,county_fips_list 是字符串数组。

建议我如何优化它?这只是更大查询的一部分,但已隔离这是它的瓶颈

我是否应该将连接之外的县 fips 移至下面的 where 子句?预先感谢您!

© www.soinside.com 2019 - 2024. All rights reserved.