我有一个多边形表(千个)和一个点表(百万个)。这两个表在几何列上都有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方法还要慢。有什么想法吗?
答案 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。