优化面查询中的很大点


9

我有一个地址点的国家数据集(3700万个)和一个洪水泛滥的多边形数据集(200万个),类型为MultiPolygonZ,某些多边形非常复杂,最大ST_NPoints约为200,000。我正在尝试使用PostGIS(2.18)识别洪泛多边形中的地址点,并将其写入具有地址ID和洪灾风险详细信息的新表中。我从地址角度(ST_Within)进行了尝试,但是从洪水区域角度(ST_Contains)开始进行了交换,其理由是存在大面积区域而根本没有洪水风险。两个数据集都已重新投影到4326,并且两个表都具有空间索引。我下面的查询已经运行了3天,并且没有任何迹象表明很快会完成!

select a.id, f.risk_factor_1, f.risk_factor_2, f.risk_factor_3
into gb.addresses_with_flood_risk
from gb.flood_risk_areas f, gb.addresses a
where ST_Contains(f.the_geom, a.the_geom);

有没有更好的方法来运行此?另外,对于这种类型的长时间运行的查询,除了查看资源利用率和pg_stat_activity之外,监视进度的最佳方法是什么?


我的原始查询完成了3天,虽然还可以,但是我在其他工作上步履蹒跚,所以我从来没有花时间尝试解决方案。但是,到目前为止,我刚刚重新访问了该文档并完成了建议。我使用了以下内容:

  1. 使用此处建议的ST_FishNet解决方案在英国建立了50公里的网格
  2. 将生成的网格的SRID设置为British National Grid并在其上建立空间索引
  3. 使用ST_Intersection和ST_Intersects裁剪了我的洪水数据(MultiPolygon)(这里唯一需要注意的是,我必须在geom上使用ST_Force_2D,因为shape2pgsql添加了Z索引
  4. 使用相同的网格裁剪我的点数据
  5. 在行上创建索引,在每个表上创建col和空间索引

我现在准备运行我的脚本,将遍历行和列的结果填充到一个新表中,直到覆盖全国为止。但是只是检查了我的洪水数据,一些最大的多边形似乎在翻译中丢失了!这是我的查询:

SELECT g.row, g.col, f.gid, f.objectid, f.prob_4band, ST_Intersection(ST_Force_2D(f.geom), g.geom) AS geom 
INTO rofrse.tmp_flood_risk_grid 
FROM rofrse.raw_flood_risk f, rofrse.gb_grid g
WHERE (ST_Intersects(ST_Force_2D(f.geom), g.geom));

我的原始数据如下所示:

原始洪水数据

但是剪辑后看起来像这样:

网格洪水数据

这是一个“缺失”多边形的示例:

“缺少”多边形


我刚刚意识到我们在汉城举行的FOSS4G会面,并谈论了ESRI定位器枢纽的奇迹:-)
John Powell

您是否曾经完成过分而治之的方法?您可以使用这种方法更新基准时间吗?
安德鲁(Andrew)'18

Answers:


6

首先要回答您的最后一个问题,请参阅这篇文章关于能够监视查询进度的可取性。这个问题很困难,并且会在空间查询中加剧,因为您知道已经对99%的地址进行了扫描以包含在泛洪多边形中(可以从基础表扫描实现中的循环计数器中获取),因此不一定如果最后1%的地址恰好与具有最多点的洪水多边形相交,而前99%的地址与某个微小区域相交,则有帮助。这是为什么EXPLAIN有时对空间无益的原因之一,因为它可以指示要扫描的行,但是出于明显的原因,它没有考虑多边形的复杂性(因此,很大一部分任何相交/相交类型查询的运行时间)。

第二个问题是,如果您看类似

EXPLAIN 
SELECT COUNT(a.id) 
FROM sometable a, someothertable b
WHERE ST_Intersects (a.geom, b.geom)

遗漏了许多细节之后,您将看到类似的内容:

_st_intersects(a.geom, b.geom)
   ->  Bitmap Index Scan on ix_spatial_index_name  (cost...rows...width...))
   Index Cond: (a.geom && geom)

最终条件&&表示在对实际几何图形进行任何更精确的交点之前,先进行边界框检查。这显然是明智的,并且是R-Trees如何工作的核心。但是,我过去也曾处理过英国的洪水数据,因此,如果(多)多边形非常广泛,请熟悉数据结构-如果河流在例如45度-您会得到巨大的边界框,这可能会迫使在非常复杂的多边形上检查大量潜在的相交点。

对于“我的查询已经运行了3天,我不知道我们是1%还是99%”问题,我唯一能想到的解决方案是对假人使用分而治之我的意思是,将您的区域分成较小的块,然后分别在plpgsql中循环或在控制台中显式运行它们。这具有将复杂的多边形切割成多个部分的优势,这意味着多边形检查中的后续点将在较小的多边形上工作,并且多边形的边界框要小得多。

在杀死了整个英国已经运行了一周以上的查询之后,我成功地将英国分成50公里乘50公里的区域来一天内运行查询。顺便说一句,我希望您上面的查询是CREATE TABLE或UPDATE,而不仅仅是SELECT。当您更新一个表地址(基于位于洪水多边形中的地址)时,无论如何都要扫描整个表,地址,因此实际上在其上具有空间索引根本没有帮助。

编辑:在一张图像上值一千个单词的基础上,这是一些英国洪水数据的图像。有一个非常大的多边形,其边界框覆盖了整个区域,因此很容易看到,例如,首先将洪水多边形与红色网格相交,西南角的正方形会突然只被测试针对多边形的一小部分。

在此处输入图片说明


约翰,您好,非常感谢您提供全面的答案,我会按照您对网格方法的建议进行操作,听起来像是一个非常明智的建议,我并不是真的想简化并失去准确性。我将以一个块为基准进行测试,然后并行运行,这几天使用云计算要容易得多!再次感谢
Mark Varley

嗨,马克,不用担心,如果您认为有帮助,请考虑接受答案。它有助于保持站点整洁,没有可接受答案的问题是堆栈交换站点关注的指标之一。
John Powell

好的,所有的事情都做完了,这是我的第一篇文章,通常我会从详细的主题和有用的答复中找到答案。大约3天后,查询终于在今天早上结束,虽然还算不错,但是今天您将按照您的建议将其分解成多个块,以提高性能。再次感谢约翰的帮助,也许八月份在波恩见到您!
Mark Varley

我添加了一张照片,尽管我意识到您已经获得了:D图像,但它可能有助于其他人形象化我的想法。是的,我几乎可以肯定会去Foss4G UK,并且会考虑波恩。
John Powell
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.