PostgreSQL 9.3.5 ve PostGIS 2.1.4 kullanarak OSM verileri için bazı istatistikleri hesaplamak çalışıyorum. Geofabrik'ten indirdiğim küçük bir bavyera özütü ile başladım. Db şeması normal API 0.6 şemasıdır, veriler döküm yaklaşımıyla Postgres'e aktarılmıştır (osmosis ile birlikte gelen pgsnapshot_schema_0.6 * .sql betikleri kullanılarak). ANALİZ VAKUMU da yapıldı.
Kullandığım tek ısmarlama şey, tüm idari sınır ilişkileri için çokgenler içeren bir çokgen tablo. Çokgen geometrisi hiçbir şekilde basitleştirilmemiştir.
Şimdi elde etmeye çalıştığım şey bavaria'nın admin = 6 sınırları içindeki tüm düğümleri saymak. İşte benim SQL sorgusu:
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;
Postgres iç içe bir döngü birleştirme yapıyor ve her yönetici = 6 sınır için tüm düğümleri tarar çünkü bu sorgunun çalışma zamanı korkunç. FYI, bavyera 98 admin = 6 çokgene ayrılmıştır ve bavyera ekstraktında yaklaşık 30 milyon düğüm vardır.
Bu alt optimal sorgu yürütülmesinden kaçınmak ve Postgres'e tüm düğümleri yalnızca bir kez taraması gerektiğini söylemek mümkün mü (örneğin, sonuç kümesindeki ilgili çokgen için bir sayaç artırarak veya ipuçlarını kullanarak)?
Düzenle:
1) Bavyera düğümlerinde uzamsal bir dizin var:
CREATE INDEX idx_nodes_geom ON bavaria.nodes USING gist (geom);
2) sorgu planı şuna benzer:
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)
Aşağıdaki iki dizin oluşturdum, ancak sorgu planı (ve çalışma zamanı) değişmedi
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
ve admin_level
) için kullandığınız etiketleri tablodaki fazladan sütunlara çıkarın ve bunları doğrudan kullanın.