如何改善空间连接?

How to improve spatial join?

我是 运行 这个空间连接,针对 400 行大约 2500 万行的两个多边形图层。我已经检查了无效的几何图形,但没有人出现..

我已将存储设置为外部存储并在 geom 字段中创建索引作为要点。

查询计划

嵌套循环内连接 2. 对table2进行seq扫描作为att 3. 作为 g 在 ltable1 上进行位图堆扫描 重新检查条件:(g.geom && att.geom) 4. 使用 table1_geom_idx 进行位图索引扫描 索引条件:(g.geom && att.geom)

但是性能真的很差,服务器断开前的最后一次尝试花了20多个小时才失败,因为服务器断开。

我正在使用 postgresql 11 postgis,我在 aws 实例中尝试了本地和远程桌面,两者的性能相似。

SELECT g.field1,
    att.ogc_fid,
    st_intersection(g.geom, att.geom) AS intersect_geom,
    st_area(g.geom) AS geom_area,
    st_area(st_intersection(g.geom, att.geom)) AS intersect_area
   FROM table1 g
     JOIN table2 att ON g.geom && att.geom;

四处走动后,我也尝试了子查询,但不确定是否可行:

WITH g AS (
         SELECT field1,
            count(*) AS num_polygons,
            table1.geom
           FROM table1
          GROUP BY table1.field1, table1.geom
        )
SELECT g.field1,
    att.field2,
    st_intersection(g.geom, att.geom) AS intersect_geom,
    st_area(g.geom) AS geom_area,
    st_area(st_intersection(g.geom, att.geom)) AS intersect_area
   FROM g
     JOIN table2 att ON g.geom && att.geom
     WHERE ST_IsValid(att.geom) AND ST_IsValid(g.geom);

我想提高性能,如有任何帮助,我们将不胜感激。

此答案假定几何列已正确编入索引,例如使用 gist:

CREATE INDEX idx_tb1_geom ON table1 USING gist (geom);
CREATE INDEX idx_tb2_geom ON table2 USING gist (geom);

您的查询在空间上连接了包含 400 和 2500 万条记录的两个表 没有 WHERE 子句,这意味着它可能 return 两个表的笛卡尔积。这是一个巨大的结果集!

我使用包含 403 条记录和 table2 500 万条记录的 table1 复制了您的环境,并且它的工作速度非常快。为了说明我的观点,如果我们简单地计算重叠的几何数量(而不实际检索它们),查询运行得非常快:

EXPLAIN (ANALYSE,COSTS OFF)  
SELECT count(att.*)
FROM table1 g
JOIN table2 att ON g.geom && att.geom;
                                            QUERY PLAN                                             
---------------------------------------------------------------------------------------------------
 Aggregate (actual time=516.299..516.300 rows=1 loops=1)
   ->  Nested Loop (actual time=6.118..501.909 rows=281212 loops=1)
         ->  Seq Scan on table1 g (actual time=0.060..0.312 rows=403 loops=1)
         ->  Bitmap Heap Scan on table2 att (actual time=0.187..1.198 rows=698 loops=403)
               Recheck Cond: (g.geom && geom)
               Heap Blocks: exact=279398
               ->  Bitmap Index Scan on idx_tb2_geom (actual time=0.108..0.108 rows=698 loops=403)
                     Index Cond: (geom && g.geom)
 Planning Time: 0.505 ms
 Execution Time: 519.337 ms

请注意,查询在 519ms 中过滤了 281212 个几何图形,这对于数据量而言并不是最差的性能。但是,如果您决定检索这 281212 个几何图形,情况就会大不相同,因为您会遇到其他瓶颈,例如可用内存和网络速度。

一条经验法则:永远不要将数据带到软件中,而是将软件带到数据中!这意味着在将数据加载到应用程序之前,您应该尽可能多地在数据库中处理数据。