优化 PostGIS 中 ST_Buffer 层交集的查询
Optimize query for intersection of ST_Buffer layer in PostGIS
我在 PostGIS 中存储了两个表:
1. 具有大约 590000 行(layerA)和
2. 单个多部分(1 行)向量层 (layerB)
并且我想找到 layerA 和 layerB 中每个多边形缓冲区之间的交集区域。到目前为止我的查询是
SELECT ST_Area(ST_Intersection(a.geom, b.geom)) AS myarea, a.gid AS mygid FROM
(SELECT ST_Buffer(geom, 500) AS geom, gid FROM layerA) AS a,
layerB AS b
到目前为止,我可以看到我的查询正在运行,但我计算出它需要 17 个小时才能完成(使用我的 PC)。有没有其他方法可以更高效、更快速地执行此查询?
如果在交点和面积计算之前检查重叠区域的交点怎么办,可能会缩短时间。
SELECT ST_Area(ST_Intersection(a.geom, b.geom)) AS myarea, a.gid AS mygid FROM
(SELECT ST_Buffer(geom, 500) AS geom, gid FROM layerA) AS a,
layerB AS b WHERE ST_intersects(a.geom, b.geom)
您可能会在 gis.stackexchange.com.
获得更多答案
您可以做几件事。
您应该确保在索引的帮助下首次过滤实际相交的多边形。
在具有许多几何图形的 table 上放置一个要点索引,并在缓冲的几何图形上使用 st_dwithin(geom,500) 而不是 st_intersects。那是因为缓冲几何不能使用在非缓冲几何上计算的索引。
另外,你说你有多个多边形。如果每个多边形中实际上有超过 1 个多边形,那么在构建索引之前先将多边形拆分为单个多边形可能会提高速度。这将使 the.index 完成更多的工作。
出于同样的原因,postgis 中实际上有一个功能可以将单个多边形分割成更小的部分。
ST_SubDivide
所以首先使用ST_Dump得到单个多边形:
CREATE table a_singles AS
SELECT id, (ST_Dump(geom)).geom geom FROM a;
然后创建索引:
CREATE INDEX idx_a_s_geom
ON a_singles
USING gist(geom);
最后查询,类似
SELECT ST_Area(ST_Intersection(ST_Buffer(a_s.geom,500), b.geom))
FROM a_singles AS a_s
INNER JOIN b
on ST_DWithin(a_s.geom,b.geom,500);
如果仍然很慢,您可以开始玩 ST_SubDivide。
还有一件事。如果 table b 中的单个多边形包含许多几何图形,也将它们拆分并在那里放置一个索引。
经过所有这些事情,它也可能很慢。这取决于实际相交的分割多边形中有多少顶点(对于 st_dwithin 还取决于具有重叠边界框的多边形中有多少顶点)
但是现在您没有任何索引可以帮助您,所以这应该会大大加快速度。
我在 PostGIS 中存储了两个表: 1. 具有大约 590000 行(layerA)和 2. 单个多部分(1 行)向量层 (layerB)
并且我想找到 layerA 和 layerB 中每个多边形缓冲区之间的交集区域。到目前为止我的查询是
SELECT ST_Area(ST_Intersection(a.geom, b.geom)) AS myarea, a.gid AS mygid FROM
(SELECT ST_Buffer(geom, 500) AS geom, gid FROM layerA) AS a,
layerB AS b
到目前为止,我可以看到我的查询正在运行,但我计算出它需要 17 个小时才能完成(使用我的 PC)。有没有其他方法可以更高效、更快速地执行此查询?
如果在交点和面积计算之前检查重叠区域的交点怎么办,可能会缩短时间。
SELECT ST_Area(ST_Intersection(a.geom, b.geom)) AS myarea, a.gid AS mygid FROM
(SELECT ST_Buffer(geom, 500) AS geom, gid FROM layerA) AS a,
layerB AS b WHERE ST_intersects(a.geom, b.geom)
您可能会在 gis.stackexchange.com.
获得更多答案您可以做几件事。
您应该确保在索引的帮助下首次过滤实际相交的多边形。
在具有许多几何图形的 table 上放置一个要点索引,并在缓冲的几何图形上使用 st_dwithin(geom,500) 而不是 st_intersects。那是因为缓冲几何不能使用在非缓冲几何上计算的索引。
另外,你说你有多个多边形。如果每个多边形中实际上有超过 1 个多边形,那么在构建索引之前先将多边形拆分为单个多边形可能会提高速度。这将使 the.index 完成更多的工作。
出于同样的原因,postgis 中实际上有一个功能可以将单个多边形分割成更小的部分。 ST_SubDivide
所以首先使用ST_Dump得到单个多边形:
CREATE table a_singles AS
SELECT id, (ST_Dump(geom)).geom geom FROM a;
然后创建索引:
CREATE INDEX idx_a_s_geom
ON a_singles
USING gist(geom);
最后查询,类似
SELECT ST_Area(ST_Intersection(ST_Buffer(a_s.geom,500), b.geom))
FROM a_singles AS a_s
INNER JOIN b
on ST_DWithin(a_s.geom,b.geom,500);
如果仍然很慢,您可以开始玩 ST_SubDivide。
还有一件事。如果 table b 中的单个多边形包含许多几何图形,也将它们拆分并在那里放置一个索引。
经过所有这些事情,它也可能很慢。这取决于实际相交的分割多边形中有多少顶点(对于 st_dwithin 还取决于具有重叠边界框的多边形中有多少顶点)
但是现在您没有任何索引可以帮助您,所以这应该会大大加快速度。