อัปเดตแถวฐานข้อมูลด้วยคะแนนที่อยู่ในรูปหลายเหลี่ยม


10

ฉันมี PostGIS / Postgresql DB ที่มีสองตารางอยู่ในนั้น หนึ่งที่มีรูปทรงเรขาคณิตจุดและอื่น ๆ ที่แสดงถึงขอบเขตของประเทศเป็นรูปหลายเหลี่ยม ฉันต้องการเพิ่มชื่อประเทศที่แต่ละจุดตัดกับแต่ละแถวในตารางพอยต์ของฉัน อาจเป็นแบบสอบถามแบบใช้ปรับปรุงที่มีขนาดใหญ่ ฉันคิดว่านี่เป็นไปได้ที่จะใช้ SQL แบบตรง แต่ไม่รู้ว่าจะเริ่มต้นตรงไหน คำแนะนำใด ๆ เกี่ยวกับเรื่องนี้จะได้รับการชื่นชมอย่างมาก ...

คำตอบ:


9

ตัวเลือกอื่นโดยไม่จำเป็นต้องใช้ฟังก์ชั่น

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

ฉันสงสัย (แม้ว่าฉันยังไม่ได้ทดสอบ) ว่ามันจะเร็วกว่าการใช้ฟังก์ชันซ้อนในตัวอย่างของคุณ

ผลลัพธ์จากการเรียกใช้ของฉันอธิบาย (หวังว่าภาพลักษณ์ของคุณจะคล้ายกัน) หากคุณมีผลการสแกน Seq มากขึ้นแสดงว่าเป็นสิ่งที่ควรพิจารณาบางทีดัชนีอาจไม่ได้รับการตั้งค่าอย่างเหมาะสม

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)"

! น่ากลัว ดูเหมือนว่าจะเร็วขึ้นมากเช่นกัน ขอบคุณ!
AdamEstrada

4

ตกลง ... ฉันทำการแฮ็คเล็กน้อยและพบว่า SQL FUNCTION ทำให้ฉันได้รับประโยชน์มากที่สุด ใครมีความคิดที่จะนำสิ่งนี้ไปที่สะพาน?

 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.