Çokgen sorgusunda çok büyük bir noktayı optimize etme


9

Adres noktalarının ulusal veri kümesi (37 milyon) ve MultiPolygonZ türü sel anahatlarının (2 milyon) çokgen veri kümesi var, bazı çokgenler çok karmaşık, maksimum ST_NPoints yaklaşık 200.000. Hangi adres noktaları taşkın poligon olan PostGIS (2.18) kullanarak tanımlamak ve bu adres kimliği ve sel riski ayrıntıları ile yeni bir tabloya yazmak çalışıyorum. Ben bir adres perspektifinden (ST_Within) denedim ama sonra sel alanı perspektif (ST_Contains) başlayarak bu takas, hiç sel riski olmayan geniş alanlar olması. Her iki veri kümesi de 4326 olarak yeniden projelendirildi ve her iki tabloda da uzamsal bir dizin var. Aşağıdaki sorgum 3 gündür çalışıyor ve yakında herhangi bir zamanda bitirme belirtisi göstermiyor!

select a.id, f.risk_factor_1, f.risk_factor_2, f.risk_factor_3
into gb.addresses_with_flood_risk
from gb.flood_risk_areas f, gb.addresses a
where ST_Contains(f.the_geom, a.the_geom);

Bunu çalıştırmanın daha uygun bir yolu var mı? Ayrıca, bu türden uzun süren sorgular için, kaynak kullanımını ve pg_stat_activity'ye bakmak dışında ilerlemeyi izlemenin en iyi yolu nedir?


Benim orijinal sorgu 3 gün de olsa Tamam tamamlandı ve ben başka bir iş ile sidetracked var, bu yüzden çözüm denemek için zaman ayırmak zorunda asla. Ancak ben sadece bu ziyaret ve şimdiye kadar iyi öneriler yoluyla çalışma var. Aşağıdakileri kullandım:

  1. Burada önerilen ST_FishNet çözümünü kullanarak İngiltere üzerinde 50 km'lik bir ızgara oluşturdu
  2. Oluşturulan ızgaranın SRID'sini British National Grid'e ayarlayın ve üzerine bir uzamsal indeks oluşturdu.
  3. Şekil2pgsql bir Z dizini ekledi gibi taşkın verilerimi (MultiPolygon) ST_Intersection ve ST_Intersects kullanarak kırpılmış (sadece gotcha burada geo_ ST_Force_2D kullanmak zorundaydı
  4. Puan verilerimi aynı ızgarayı kullanarak kırptım
  5. Satırlarda dizinler ve tabloların her birinde sütun ve uzamsal dizin oluşturuldu

Senaryomu şimdi çalıştırmaya hazırım, tüm ülkeyi kaplayana kadar sonuçları yeni bir tabloya yerleştiren satır ve sütunlar üzerinde yinelenecek. Ama sadece taşkın verilerimi kontrol ettim ve en büyük çokgenlerin bazıları çeviri sırasında kayboldu! Bu benim sorgu:

SELECT g.row, g.col, f.gid, f.objectid, f.prob_4band, ST_Intersection(ST_Force_2D(f.geom), g.geom) AS geom 
INTO rofrse.tmp_flood_risk_grid 
FROM rofrse.raw_flood_risk f, rofrse.gb_grid g
WHERE (ST_Intersects(ST_Force_2D(f.geom), g.geom));

Orijinal verilerim şöyle:

Orijinal taşkın verileri

Ancak yazı kırpma böyle görünüyor:

Izgaralı taşkın verileri

Bu, "eksik" bir çokgene örnektir:

"Eksik" çokgen


Az önce Seul'deki FOSS4G'de bir araya geldiğimizi fark ettim ve ESRI konumlandırıcı merkezinin harikaları hakkında konuştuk :-)
John Powell

Böl ve fethet yaklaşımını hiç bitirdiniz mi? Kıyaslama sürelerini bu yaklaşımla güncelleyebilir misiniz?
andrew

Yanıtlar:


6

Önce son sorunuzu cevaplamak için bu gönderiye bakınsorguların ilerlemesini izlemenin istenmesi hakkında. Sorun zordur ve altta yatan tablo tarama uygulamasındaki döngü sayacından alabileceğiniz bir taşkın poligonunda içerilmek üzere zaten taranan adreslerin% 99'unun zorunlu olarak bulunmadığından, uzamsal bir sorguda birleştirilecektir. adreslerin son% 1'inin en çok puana sahip bir sel poligonu ile kesişmesi durumunda yardımcı olurken, önceki% 99 ufak bir alanla kesişir. Taranacak satırların bir göstergesini verdiğinden, ancak açık nedenlerden dolayı çokgenlerin karmaşıklığını (ve dolayısıyla büyük bir oranı) dikkate almadığından, EXPLAIN'in bazen uzamsal olarak yardımcı olmamasının nedenlerinden biridir. (Kesinti / kavşak türü sorgularının).

İkinci bir sorun şudur:

EXPLAIN 
SELECT COUNT(a.id) 
FROM sometable a, someothertable b
WHERE ST_Intersects (a.geom, b.geom)

birçok ayrıntıyı kaçırdıktan sonra şöyle bir şey göreceksiniz:

_st_intersects(a.geom, b.geom)
   ->  Bitmap Index Scan on ix_spatial_index_name  (cost...rows...width...))
   Index Cond: (a.geom && geom)

Son koşul, &&, gerçek geometrilerin daha doğru kesişimini yapmadan önce sınırlayıcı bir kutu kontrolü yapmak anlamına gelir. Bu açıkça mantıklı ve R-Ağaçlarının nasıl çalıştığının merkezinde. Bununla birlikte, geçmişte İngiltere taşkın verileri üzerinde de çalıştım, bu yüzden (Çok) Çokgenler çok genişse, verilerin yapısına aşinayım - bir nehir akarsa, bu sorun özellikle akut derece - çok karmaşık çokgenler üzerinde çok sayıda potansiyel kavşak kontrol edilmesini zorlayabilir büyük sınırlayıcı kutuları olsun.

"Benim sorgu 3 gün boyunca çalışıyor ve% 1 veya% 99 olup olmadığını bilmiyorum" sorun için gelip tek çözüm aptallar için bir tür bölme ve fethetmek için kullanmaktır Yani, bölgenizi daha küçük parçalara ayırın ve bunları plpgsql'deki bir döngüde veya açıkça konsolda ayrı ayrı çalıştırın. Bu, karmaşık çokgenleri parçalara ayırma avantajına sahiptir, bu da çokgen kontrollerindeki sonraki noktanın daha küçük çokgenler üzerinde çalıştığı ve çokgenlerin sınırlayıcı kutularının çok daha küçük olduğu anlamına gelir.

Tüm İngiltere'de bir haftadan fazla süredir devam eden bir sorguyu öldürdükten sonra İngiltere'yi 50 km x 50 km'lik bloklara bölerek bir günde sorgu çalıştırmayı başardım. Bir yana, umarım yukarıdaki sorgunuz CREATE TABLE veya UPDATE ve sadece bir SELECT değildir. Bir taşkın poligonuna bağlı olarak bir tabloyu, adresleri güncellerken, güncellenmekte olan tüm tabloyu taramanız, yine de adresleri taramanız gerekir, bu yüzden aslında üzerinde uzamsal bir dizin olması hiç yardımcı olmaz.

EDIT: Bir görüntü bin kelimeye bedel temelinde, işte bazı İngiltere sel verilerinin bir görüntü. Sınırlama kutusu tüm alanı kaplayan çok büyük bir çokgen vardır, bu nedenle ilk önce sel poligonunu kırmızı ızgara ile keserek, güneybatı köşesindeki karenin aniden sadece nasıl test edileceğini görmek kolaydır. çokgenin küçük bir alt kümesine karşı.

resim açıklamasını buraya girin


Merhaba John ve kapsamlı cevap için çok teşekkür ederim, ızgara yaklaşımı hakkındaki tavsiyenizi takip edeceğim, çok mantıklı bir öneri gibi geliyor, gerçekten basitleştirmek ve doğruluğunu kaybetmek istemiyorum. Bir blokla kıyaslayacağım ve daha sonra paralel olarak çalışacağım, bu gün bulutla çok daha kolay! Tekrar teşekkürler
Mark Varley

Merhaba Mark, endişelenmeyin, lütfen yardımcı olduğunu düşünüyorsanız cevabı kabul etmeyi düşünün. Sitenin temiz kalmasına yardımcı olur, kabul edilen cevapları olmayan sorular, yığın alışveriş sitelerinin baktığı metriklerden biridir.
John Powell

Tamam hepsi bitti, bu benim ilk yazım, normalde ayrıntılı konuları ve yardımcı yanıtları buluyorum. Sorgu nihayet bu sabah yaklaşık 3 gün sonra çok kötü olmayan ama bugün tavsiyelerinizi takip edip daha iyi performans için parçalara ayıracak. Yardımın için tekrar teşekkürler John ve belki Ağustos ayında Bonn'da görüşürüz!
Mark Varley

Bir fotoğraf ekledim, ancak resme sahip olduğunuzu anlıyorum: D, başkalarının hakkında ne olduğumu görselleştirmesine yardımcı olabilir. Evet, neredeyse kesinlikle Foss4G İngiltere'ye gidiyorum ve Bonn'u düşüneceğim.
John Powell
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.