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:
- Ein 50 km - Raster über das Vereinigte Königreich der ST_FishNet - Lösung vorgeschlagen erstellt hier
- Setzen Sie die SRID des generierten Rasters auf British National Grid und erstellen Sie einen räumlichen Index darauf
- 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
- Meine Punktdaten wurden mit demselben Raster abgeschnitten
- 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:
Wie auch immer, nach dem Ausschneiden sieht es so aus:
Dies ist ein Beispiel für ein "fehlendes" Polygon:
quelle
Antworten:
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
Sie werden so etwas sehen, nachdem Sie viele Details verpasst haben:
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.
quelle