【发布时间】:2019-03-25 09:45:18
【问题描述】:
我有多边形表(千)和点表(百万)。两个表在几何列上都有 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 方法还要慢。有什么想法吗?
【问题讨论】:
-
我不知道 postgis,所以你能澄清一下:当你调用
ST_Contains时,my_points上是否使用了索引?什么是“不必要的慢”,你能给我们实际的时间吗?而且只有数千个(多少个?)多边形,每个多边形只包含点表中的一个点(我假设只是一行),对吗?也许 EXPLAIN ANALYZE 会很有用。 -
是的,两个表都有几何列索引。此外,每个多边形可以包含许多点,但一个点在一个多边形内。确切的数字并不重要,我有多个数据集,这取决于机器。对于 ~5000 点和 ~1m 点,在我的数据库服务器上大约需要 15 秒。
-
您在这两列上究竟创建了什么样的索引?请edit您的问题并为两个表添加
create table语句,包括所有create index语句。根据 to the manualST_Contains()应该能够在这些列上使用 GIST 索引。正如 404 已经说过的:使用explain (analyze, buffers)生成的执行计划也会有所帮助
标签: postgresql postgis