Max Gabrielsson 对 DuckDB 的新空间连接优化进行了极其详细的概述。
考虑以下查询,该查询计算由纽约市社区制表区域多边形定义的每个社区的纽约市花旗自行车出行次数,并返回前三名:
选择社区, 计数( * ) AS num_rides 来自骑行 JOIN hoods ON ST_Intersects( 游乐设施.start_geom ,兜帽.geom ) 按邻里分组 按乘车次数降序排列 限制3 ;
rides 表包含 58,033,724 行。hoods 表包含 310 个街区的多边形。
如果没有优化的空间连接,此查询需要嵌套循环连接,执行 58m * 310 ~= 180 亿次昂贵的ST_Intersects()
操作。这在用于基准测试的 36GB MacBook M3 Pro 上大约花费了 30 分钟。
第一个优化方案——从 DuckDB 1.2.0 开始实现——使用了“分段合并连接”。这种方法充分利用了边界框交集计算速度更快的优势,尤其是在将边界框(即最小边界矩形,MBR)预先缓存到二进制GEOMETRY
表示中的情况下。
重写查询以使用快速边界框交集,然后仅在这些匹配上运行更昂贵的ST_Intersects()
过滤器,将运行时间从 1800 秒缩短至 107 秒。
第二个优化是在 2025 年 5 月使用新的 SPATIAL_JOIN 运算符添加到DuckDB 1.3.0中的,它更加复杂。
DuckDB 现在可以识别空间连接何时针对大量数据进行操作,并自动为连接的两个表中较大的一个表构建内存中的边界框 R 树。
这个新的 R-Tree 进一步加速了连接的边界框交叉部分,并将运行时间缩短至仅 30 秒。
原文: https://simonwillison.net/2025/Aug/23/spatial-joins-in-duckdb/#atom-everything