Sto cercando di calcolare alcune statistiche per i dati OSM usando PostgreSQL 9.3.5 e PostGIS 2.1.4. Ho iniziato con un piccolo estratto bavarese che ho scaricato da Geofabrik. Lo schema db è il normale schema API 0.6, i dati sono stati importati tramite l'approccio dump in Postgres (usando gli script pgsnapshot_schema_0.6 * .sql forniti con l'osmosi). ANALYZE VACUUM è stato anche eseguito.
L'unica cosa su misura che sto usando è una tabella poligonale che contiene multipoligoni per tutte le relazioni amministrative di confine. La geometria poligonale non è stata semplificata in alcun modo.
Ciò che ora sto cercando di ottenere è contare tutti i nodi che si trovano all'interno dell'amministratore = 6 confini della Baviera. Ecco la mia query SQL:
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;
Il runtime di questa query è terribile perché Postgres sta eseguendo un join loop nidificato ed esegue la scansione di tutti i nodi per ogni limite admin = 6. Cordiali saluti, la Baviera è divisa in 98 admin = 6 poligoni e ci sono circa 30 milioni di nodi nell'estratto della Baviera.
È possibile evitare l'esecuzione di una query non ottimale e dire a Postgres che dovrebbe scansionare tutti i nodi una sola volta (ad esempio, incrementando un contatore per il poligono corrispondente nel set di risultati o usando i suggerimenti)?
Modificare:
1) esiste un indice spaziale sui nodi bavaresi:
CREATE INDEX idx_nodes_geom ON bavaria.nodes USING gist (geom);
2) il piano di query è simile al seguente:
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)
Ho creato i seguenti due indici, ma il piano di query (e il runtime) non sono cambiati
CREATE INDEX relpolygons_tags_boundary on bavaria.relpolygons( (tags->'boundary') );
CREATE INDEX relpolygons_tags_admin on bavaria.relpolygons( (tags->'admin_level') );
ANALYZE bavaria.relpolygons;
boundary
e admin_level
) in colonne extra sulla tabella e usali direttamente.