Optimieren eines sehr großen Punkts in der Polygonabfrage


9

Ich habe einen nationalen Datensatz mit Adresspunkten (37 Millionen) und einen Polygon-Datensatz mit Flutkonturen (2 Millionen) vom Typ MultiPolygonZ. Einige der Polygone sind sehr komplex. Die maximale Anzahl an ST_NPoints liegt bei 200.000. Ich versuche mit PostGIS (2.18) zu identifizieren, welche Adresspunkte sich in einem Hochwasserpolygon befinden, und diese in eine neue Tabelle mit Adress-ID und Details zum Hochwasserrisiko zu schreiben. Ich habe es aus einer Adressperspektive (ST_Within) versucht, es dann aber ausgehend von der Hochwassergebietsperspektive (ST_Contains) ausgetauscht, wobei der Grund dafür ist, dass es große Gebiete ohne Hochwasserrisiko gibt. Beide Datensätze wurden auf 4326 neu projiziert und beide Tabellen haben einen räumlichen Index. Meine unten stehende Abfrage läuft seit 3 ​​Tagen und zeigt keine Anzeichen für eine baldige Fertigstellung!

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);

Gibt es eine optimalere Möglichkeit, dies auszuführen? Was ist bei lang laufenden Abfragen dieses Typs die beste Möglichkeit, den Fortschritt zu überwachen, außer die Ressourcennutzung und pg_stat_activity zu untersuchen?


Meine ursprüngliche Anfrage war OK, wenn auch für 3 Tage, und ich wurde von anderen Arbeiten abgelenkt, sodass ich nie die Zeit darauf verwenden musste, die Lösung auszuprobieren. Allerdings habe ich dies gerade noch einmal besucht und die Empfehlungen durchgearbeitet, soweit so gut. Ich habe folgendes verwendet:

  1. Ein 50 km - Raster über das Vereinigte Königreich der ST_FishNet - Lösung vorgeschlagen erstellt hier
  2. Setzen Sie die SRID des generierten Rasters auf British National Grid und erstellen Sie einen räumlichen Index darauf
  3. Ich habe meine Flutdaten (MultiPolygon) mit ST_Intersection und ST_Intersects abgeschnitten (nur hier musste ich ST_Force_2D für das Geom verwenden, da shape2pgsql einen Z-Index hinzufügte
  4. Meine Punktdaten wurden mit demselben Raster abgeschnitten
  5. Erstellt Indizes für die Zeile und Spalte sowie räumlicher Index für jede der Tabellen

Ich bin jetzt bereit, mein Skript auszuführen. Ich werde die Zeilen und Spalten durchlaufen, in denen die Ergebnisse in einer neuen Tabelle aufgeführt sind, bis ich das ganze Land abgedeckt habe. Aber ich habe gerade meine Hochwasserdaten überprüft und einige der größten Polygone scheinen bei der Übersetzung verloren gegangen zu sein! Das ist meine Frage:

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));

Meine Originaldaten sehen folgendermaßen aus:

Ursprüngliche Hochwasserdaten

Wie auch immer, nach dem Ausschneiden sieht es so aus:

Raster-Hochwasserdaten

Dies ist ein Beispiel für ein "fehlendes" Polygon:

Polygon "fehlt"


Ich habe gerade festgestellt, dass wir uns bei FOSS4G in Seoul getroffen haben und über die Wunder des ESRI Locator Hub gesprochen haben :-)
John Powell

Haben Sie jemals den Divide and Conquer-Ansatz beendet? Können Sie die Benchmark-Zeiten mit diesem Ansatz aktualisieren?
Andrew

Antworten:


6

Um Ihre letzte Frage zuerst zu beantworten, lesen Sie diesen Beitragüber den Wunsch, den Fortschritt von Abfragen überwachen zu können. Das Problem ist schwierig und würde sich in einer räumlichen Abfrage verschärfen, da das Wissen, dass 99% der Adressen bereits in einem Flood-Polygon auf Eindämmung gescannt wurden, das Sie vom Schleifenzähler in der zugrunde liegenden Tabellen-Scan-Implementierung erhalten könnten, nicht unbedingt erforderlich wäre Hilfe, wenn die letzten 1% der Adressen ein Flutpolygon mit den meisten Punkten schneiden, während die vorherigen 99% einen winzigen Bereich schneiden. Dies ist einer der Gründe, warum EXPLAIN manchmal räumlich nicht hilfreich sein kann, da es einen Hinweis auf die zu scannenden Zeilen gibt, aber aus offensichtlichen Gründen die Komplexität der Polygone (und damit einen großen Anteil) nicht berücksichtigt der Laufzeit) von Schnittpunkten / Kreuzungsabfragen.

Ein zweites Problem ist, wenn Sie sich so etwas ansehen

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

Sie werden so etwas sehen, nachdem Sie viele Details verpasst haben:

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

Die Endbedingung && bedeutet, dass Sie eine Begrenzungsrahmenprüfung durchführen, bevor Sie die tatsächlichen Geometrien genauer schneiden. Dies ist offensichtlich sinnvoll und bildet den Kern der Funktionsweise von R-Trees. Da ich jedoch in der Vergangenheit auch an britischen Hochwasserdaten gearbeitet habe, bin ich mit der Struktur der Daten vertraut, wenn die (Multi) Polygone sehr umfangreich sind. Dieses Problem ist besonders akut, wenn ein Fluss beispielsweise bei 45 fließt Grad - Sie erhalten riesige Begrenzungsrahmen, die dazu führen können, dass eine große Anzahl potenzieller Schnittpunkte auf sehr komplexen Polygonen überprüft wird.

Die einzige Lösung, die ich für das Problem "Meine Abfrage läuft seit 3 ​​Tagen und ich weiß nicht, ob wir bei 1% oder 99% sind" finden konnte , ist die Verwendung einer Art Teilen und Erobern für Dummies Ansatz, womit ich meine, teilen Sie Ihren Bereich in kleinere Blöcke auf und führen Sie diese separat aus, entweder in einer Schleife in plpgsql oder explizit in der Konsole. Dies hat den Vorteil, dass komplexe Polygone in Teile geschnitten werden, was bedeutet, dass nachfolgende Punkte bei Polygonprüfungen an kleineren Polygonen arbeiten und die Begrenzungsrahmen der Polygone viel kleiner sind.

Ich habe es geschafft, Abfragen an einem Tag auszuführen, indem ich Großbritannien in Blöcke von 50 x 50 km aufgeteilt habe, nachdem ich eine Abfrage beendet hatte, die seit über einer Woche in ganz Großbritannien ausgeführt wurde. Abgesehen davon hoffe ich, dass Ihre obige Abfrage CREATE TABLE oder UPDATE und nicht nur SELECT ist. Wenn Sie eine Tabelle oder Adressen aktualisieren, basierend auf einem Flood-Polygon, müssen Sie die gesamte zu aktualisierende Tabelle scannen, Adressen trotzdem, sodass es überhaupt keine Hilfe ist, einen räumlichen Index darauf zu haben.

EDIT: Auf der Grundlage, dass ein Bild mehr sagt als tausend Worte, hier ein Bild einiger britischer Hochwasserdaten. Es gibt ein sehr großes Multipolygon, dessen Begrenzungsrahmen den gesamten Bereich abdeckt, sodass leicht zu erkennen ist, wie beispielsweise durch erstmaliges Schneiden des Flutpolygons mit dem roten Gitter das Quadrat in der südwestlichen Ecke plötzlich nur noch getestet wird gegen eine winzige Teilmenge des Polygons.

Geben Sie hier die Bildbeschreibung ein


Hallo John und vielen Dank für die umfassende Antwort. Ich werde Ihrer Empfehlung zum Rasteransatz folgen. Klingt nach einem sehr vernünftigen Vorschlag. Ich möchte nicht wirklich vereinfachen und die Genauigkeit verlieren. Ich werde mit einem Block vergleichen und dann parallel laufen, heutzutage viel einfacher mit Cloud!
Mark Varley

Hallo Markus, keine Sorge, bitte akzeptiere die Antwort, wenn du denkst, dass sie geholfen hat. Es hilft dabei, die Site sauber zu halten. Fragen ohne akzeptierte Antworten sind eine der Metriken, die Stack Exchange-Sites betrachten.
John Powell

OK, alles erledigt, dies ist mein erster Beitrag hier. Normalerweise finde ich die Antwort aus den detaillierten Threads und hilfreichen Antworten. Die Abfrage wurde heute Morgen nach ungefähr 3 Tagen endlich beendet, was nicht schlecht ist, aber ich werde heute Ihrem Rat folgen und ihn für eine bessere Leistung in Stücke aufteilen. Nochmals vielen Dank für Ihre Hilfe John und vielleicht bis August in Bonn!
Mark Varley

Ich habe ein Foto hinzugefügt, obwohl mir klar ist, dass Sie das Bild haben: D, es könnte anderen helfen, sich vorzustellen, worum es mir geht. Ja, ich gehe mit ziemlicher Sicherheit zu Foss4G UK und werde an Bonn denken.
John Powell
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.