我有两张表,一张有 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 中运行它时也会超时)。
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 使用地理空间连接,然后才检查现在复杂的相等条件。当然,只有在没有状态相等谓词的查询运行得相当快的情况下它才有效。
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 子句?预先感谢您!