有效地将点分配给多边形

时间:2019-03-25 09:45:18

标签: postgresql postgis

我有一个多边形表(千个)和一个点表(百万个)。这两个表在几何列上都有GIST索引。重要的是,多边形不会重叠,因此每个点都只包含一个多边形。我想生成具有这种关系的表(polygon_id + point_id)。

当然是私有解决方案

SELECT a.polygon_id, p.point_id
FROM my_polygons a
JOIN my_points p ON ST_Contains(a.geom, p.geom)

这行得通,但是我认为这没必要太慢,因为它使每个多边形与每个点都匹配-它不知道每个点只能属于一个多边形。

有什么方法可以加快速度吗?

我尝试为每个多边形循环,通过ST_Contains选择点,但仅选择结果表中尚未存在的点:

CREATE TABLE polygon2point (polygon_id uuid, point_id uuid);

DO $$DECLARE r record;
BEGIN
    FOR r IN SELECT polygon_id, geom
         FROM my_polygon             
    LOOP

    INSERT INTO polygon2point (polygon_id, point_id) 
    SELECT r.polygon_id, p.point_id
    FROM my_points p
    LEFT JOIN polygon2point t ON p.point_id = t.point_id
    WHERE t.point_id IS NULL AND ST_Contains(r.geom, p.geom);

    END LOOP;
END$$;

这比普通的JOIN方法还要慢。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

提高速度的一种方法是将subdivide的多边形缩小。

您将创建一个新表(或多边形经常更改的物化视图),对其进行索引,然后运行查询。如果细分的顶点数不超过128个,默认情况下,数据将不压缩地存储在磁盘上,从而使查询速度更快。

CREATE TABLE poly_subdivided AS 
   SELECT ST_SUBDIVIDE(a.geom, 128) AS geom , a.polygon_id 
   FROM poly;

CREATE INDEX poly_subdivided_geom_idx ON poly_subdivided  USING gist(geom);

ANALYZE poly_subdivided;

SELECT a.polygon_id, p.point_id
FROM poly_subdivided a
JOIN my_points p ON ST_Contains(a.geom, p.geom)

这是一个很棒的article