Çokgenler içinde yer alan noktalarla veritabanı satırını güncelleme


10

İçinde iki tablo olan bir PostGIS / Postgresql DB var. Biri nokta geometrileri, diğeri ülke sınırlarını çokgen olarak temsil eder. Her bir noktanın kesiştiği ülke adını nokta tablomdaki her satıra eklemek istiyorum. Belki büyük bir güncelleme sorgusu olarak. Bu düz SQL kullanarak yapmak mümkün olduğunu düşünüyorum ama nereden başlayacağımı bilmiyorum. Bu konuda herhangi bir tavsiye büyük mutluluk duyacağız ...

Yanıtlar:


9

Fonksiyona ihtiyaç duymadan başka bir seçenek

update points set country = t1.country from 
(
    select points.oid, countries.name as country from
    countries INNER JOIN points on st_contains(countries.wkb_geometry,points.wkb_geometry)
) t1 
where t1.oid = points.oid

(Test etmeme rağmen) bunun, örneğin örneğinizde olduğu gibi iç içe bir işlev kullanmaktan daha hızlı olacağından şüpheleniyorum.

Çalışmamdan elde ettiğim çıktı açıklar (umarım benzer görünürsünüz). Daha fazla Seq Scan sonucunuz varsa, bu bakılması gereken bir şeydir, belki de dizinler düzgün bir şekilde ayarlanmamıştır.

Update on points  (cost=1.18..29.40 rows=121 width=129)"
  ->  Nested Loop  (cost=1.18..29.40 rows=121 width=129)"
        Join Filter: _st_contains(countries.geometry, public.points.geometry)"
        ->  Hash Join  (cost=1.18..2.37 rows=28 width=220)"
              Hash Cond: (public.points.oid = public.points.oid)"
              ->  Seq Scan on points  (cost=0.00..1.08 rows=28 width=114)"
              ->  Hash  (cost=1.08..1.08 rows=28 width=110)"
                    ->  Seq Scan on points  (cost=0.00..1.08 rows=28 width=110)"
        ->  Index Scan using "countries_Idx" on countries  (cost=0.00..0.91 rows=1 width=414)"
              Index Cond: (geometry && public.points.geometry)"

Müthiş! Bu da çok daha hızlı görünüyor. Teşekkürler!
AdamEstrada

4

Tamam ... Biraz hack yaptım ve bir SQL FONKSİYONU beni en çok oraya götürdü. Kimse bunu köprüye almakla ilgili düşünceleriniz var mı?

 CREATE OR REPLACE FUNCTION getcountry (
       country_geom geometry
    ) RETURNS TABLE(country text) AS $$
        SELECT b.name as country FROM  
                    geonames d, world_borders b WHERE
                    $1 && b.wkb_geometry 
                    AND intersects($1, b.wkb_geometry) ;
  $$ LANGUAGE SQL;

UPDATE geonames 
    SET country = val
    FROM (SELECT getcountry(point_geom) FROM geonames) AS val
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.