我有多边形表(数千)和点数表(数百万)。两个表都在几何列上具有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方法慢。有任何想法吗?
提高速度的一种方法是将多边形变成较小的多边形。
您将创建一个新表(或多边形经常更改时的物化视图),索引它,然后运行查询。如果细分具有128个或更少的顶点,则默认情况下,数据将以未压缩的形式存储在磁盘上,从而使查询更快。
subdivide
这是一个关于这个主题的伟大的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)
。