Daha büyük OSM özütlerini işlemek için birleştirilmiş Hstore anahtarı / değeri ve uzamsal sorgu çok yavaş


13

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;

1
Bavaria.nodes konumunda uzamsal dizin var mı?
user30184

evet, soruyu düzenledim ve düğümlerdeki dizin ve sorgu planı hakkında bilgi
sağladım

3
İki seçenek. 1 - hstore etiketleri için bir dizin ekleyin. 2 - Sorgunuz ( boundaryve admin_level) için kullandığınız etiketleri tablodaki fazladan sütunlara çıkarın ve bunları doğrudan kullanın.
BradHards

Bkz. Düzenleme (3): iki dizin eklendi, ancak sorgu planında veya çalışma zamanında değişiklik olmadı.
Alf Kortig

Bazı testlerden sonra (3) 'de doğru indeksleri oluşturup oluşturmadığımı artık bilmiyorum. Şimdiye kadar, -> ve? İçin bir dizin oluşturmayı başardım. hstore operatörleri. Ancak,
sorgumda

Yanıtlar:


5

İndeks hstore etiketleri için en iyi yol dan hangi CİN veya GIST endeksleri kullanan dokümanlar , desteklemek @>, & ve?? | operatörler , yani anahtarları ve anahtar / değer çiftlerini arar. Bir B-ağacı dizini için etiketleri ayıklamak için bir işlev kullanma yaklaşımınız makul, ancak belirli anahtar / değer çiftlerini de kontrol ettiğiniz için, analizör tam bir tablo taraması seçti.

Ben bavaria.relpolygons erişim yok, ama hız sınırları ve otoyol etiketleri OSM UK için benzer bir sorguya dayanarak, bu aşağıdaki sorgu açıklamak için olsun:

SELECT count(*) 
 FROM ways 
WHERE tags @> 'highway=>motorway'::hstore 
 AND tags @> 'maxspeed=>"50 mph"'::hstore;


Aggregate  (cost=48.66..48.67 rows=1 width=0)
    ->  Index Scan using ix_ways_tags_gist on ways  (cost=0.42..48.64 rows=11 width=0)
     Index Cond: ((tags @> '"highway"=>"motorway"'::hstore) AND (tags @> '"maxspeed"=>"50 mph"'::hstore))

10 milyon sıralı bir tablo için cesaret verici olan doğrudan dizin taramasını (gist dizinini kullanarak) gösterir. Dizin basit ile oluşturuldu:

CREATE INDEX ix_ways_tags_gist ON ways USING gist (tags);

Sizi mekânsal durumu kontrol edemesem de, sanırım bunun daha az seçici olduğunu

NEREDE relpoly.tags @> '"sınır" => "yönetimsel", "admin_level" => "6"' :: hstore.

ve bu nedenle yalnızca tekrar kontrol koşulu için kullanılır.

GIN ve GIST endeksleri arasındaki fark üzerinde de bu büyük SO cevabı var . Genel bulgu, GIN dizinlerinin daha büyük ve daha yavaş oluşturulmasına rağmen, metin alma sorunlarında çok daha hızlı olmasıdır.

Çok geç cevap verdiğim için üzgünüm, ama son zamanlarda OSM ve hstore üzerinde benzer çalışmalar yapıyorum ve sadece bir kez bu soruya yıldız vermekle kalmayıp, aynı zamanda cevaplayabildiğimi keşfettim: D.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.