Estoy tratando de calcular algunas estadísticas para datos OSM usando PostgreSQL 9.3.5 y PostGIS 2.1.4. Comencé con un pequeño extracto de baviera que descargué de Geofabrik. El esquema db es el esquema API 0.6 normal, los datos se importaron a través del enfoque de volcado en Postgres (utilizando los scripts pgsnapshot_schema_0.6 * .sql que vienen con osmosis). ANÁLISIS DE VACÍO también se realizó.
Lo único personalizado que estoy usando es una tabla de polígonos que contiene multipolígonos para todas las relaciones de límites administrativos. La geometría del polígono no se simplificó de ninguna manera.
Lo que ahora estoy tratando de lograr es contar todos los nodos que están dentro de los límites admin = 6 de bavaria. Aquí está mi consulta 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;
El tiempo de ejecución de esta consulta es terrible porque Postgres está haciendo una unión de bucle anidado y escanea todos los nodos para cada límite admin = 6. Para su información, Baviera se divide en 98 admin = 6 polígonos y hay alrededor de 30 millones de nodos en el extracto de Baviera.
¿Es posible evitar esta ejecución de consulta subóptima y decirle a Postgres que debe escanear todos los nodos solo una vez (por ejemplo, incrementando un contador para el polígono correspondiente en el conjunto de resultados o usando sugerencias)?
Editar:
1) existe un índice espacial en los nodos de baviera:
CREATE INDEX idx_nodes_geom ON bavaria.nodes USING gist (geom);
2) el plan de consulta se ve así:
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)
Creé los siguientes dos índices, pero el plan de consulta (y el tiempo de ejecución) no cambió
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
y admin_level
) en columnas adicionales en la tabla y úselas directamente.