Ich versuche, mit PostgreSQL 9.3.5 und PostGIS 2.1.4 einige Statistiken für OSM-Daten zu berechnen. Ich habe mit einem kleinen Bayern-Extrakt angefangen, den ich von der Geofabrik heruntergeladen habe. Das DB-Schema ist das normale API 0.6-Schema. Die Daten wurden über den Dump-Ansatz in Postgres importiert (mithilfe der mit Osmose gelieferten Skripte pgsnapshot_schema_0.6 * .sql). ANALYSE VACUUM wurde ebenfalls durchgeführt.
Ich verwende nur eine Polygontabelle, die Multipolygone für alle administrativen Grenzbeziehungen enthält. Die Polygongeometrie wurde in keiner Weise vereinfacht.
Ich versuche jetzt, alle Knoten zu zählen, die innerhalb der Grenzen von admin = 6 von Bayern liegen. Hier ist meine SQL-Abfrage:
SELECT relpoly.id, count(node)
FROM bavaria.relpolygons relpoly, bavaria.nodes node
WHERE relpoly.tags @> '"boundary"=>"administrative","admin_level"=>"6"'::hstore
AND ST_Intersects(relpoly.geom, node.geom)
GROUP BY relpoly.id;
Die Laufzeit dieser Abfrage ist furchtbar, da Postgres einen Join mit verschachtelten Schleifen ausführt und alle Knoten nach jeder Grenze von admin = 6 durchsucht. Zu Ihrer Information, Bayern ist in 98 Admin = 6 Polygone unterteilt und der Bayern-Extrakt enthält ungefähr 30 Millionen Knoten.
Ist es möglich, diese suboptimale Abfrageausführung zu vermeiden und Postgres mitzuteilen, dass alle Knoten nur einmal durchsucht werden sollen (z. B. durch Inkrementieren eines Zählers für das entsprechende Polygon in der Ergebnismenge oder durch Verwenden von Hinweisen)?
Bearbeiten:
1) Auf den Bayernknoten existiert ein räumlicher Index:
CREATE INDEX idx_nodes_geom ON bavaria.nodes USING gist (geom);
2) Der Abfrageplan sieht folgendermaßen aus:
HashAggregate (cost=284908.49..284908.75 rows=26 width=103)
-> Nested Loop (cost=111.27..283900.80 rows=201537 width=103)
-> Bitmap Heap Scan on relpolygons relpoly (cost=4.48..102.29 rows=26 width=5886)
Recheck Cond: (tags @> '"boundary"=>"administrative", "admin_level"=>"6"'::hstore)
-> Bitmap Index Scan on relpolygons_geom_tags (cost=0.00..4.47 rows=26 width=0)
Index Cond: (tags @> '"boundary"=>"administrative", "admin_level"=>"6"'::hstore)
-> Bitmap Heap Scan on nodes node (cost=106.79..10905.50 rows=983 width=127)
Recheck Cond: (relpoly.geom && geom)
Filter: _st_intersects(relpoly.geom, geom)
-> Bitmap Index Scan on idx_nodes_geom (cost=0.00..106.55 rows=2950 width=0)
Index Cond: (relpoly.geom && geom)
3)
Ich habe die folgenden zwei Indizes erstellt, aber der Abfrageplan (und die Laufzeit) haben sich nicht geändert
CREATE INDEX relpolygons_tags_boundary on bavaria.relpolygons( (tags->'boundary') );
CREATE INDEX relpolygons_tags_admin on bavaria.relpolygons( (tags->'admin_level') );
ANALYZE bavaria.relpolygons;
quelle
boundary
undadmin_level
) verwenden, in zusätzliche Spalten in der Tabelle und verwenden Sie diese direkt.Antworten:
Der beste Weg, um hstore-Tags zu indizieren, ist die Verwendung von GIN- oder GIST-Indizes, die in den Dokumenten die Zeichen @>,?,? & Und? | Unterstützen Operatoren suchen also nach Schlüsseln und Schlüssel / Wert-Paaren. Die Verwendung einer Funktion zum Extrahieren der Tags für einen B-Tree-Index ist sinnvoll. Da Sie jedoch auch nach bestimmten Schlüssel / Wert-Paaren suchen, hat der Analysator einen vollständigen Tabellenscan ausgewählt.
Ich habe keinen Zugriff auf bavaria.relpolygons, aber basierend auf einer ähnlichen Abfrage für OSM UK zu Geschwindigkeitsbegrenzungen und Autobahn-Tags erhalte ich diese für meine Erklärung zu der folgenden Abfrage:
Dies zeigt einen direkten Index-Scan (unter Verwendung des Hauptindex), der für eine Tabelle mit 10 Millionen Zeilen ermutigend ist. Der Index wurde mit dem einfachen erstellt:
Ich kann Ihren räumlichen Zustand zwar nicht überprüfen, schätze aber, dass er weniger selektiv ist als
und würde daher nur für eine erneute Prüfung verwendet werden.
Es gibt auch diese großartige SO-Antwort auf den Unterschied zwischen GIN- und GIST-Indizes . Die allgemeine Erkenntnis ist, dass GIN-Indizes zwar größer und langsamer zu erstellen sind, jedoch bei Problemen mit der Texterfassung viel schneller sind.
Es tut mir leid, dass ich so spät geantwortet habe, aber ich habe kürzlich ähnliche Arbeiten an OSM und hstore durchgeführt und festgestellt, dass ich diese Frage nicht nur einmal gestellt habe, sondern jetzt beantworten konnte: D.
quelle