ปัญหาเพื่อนบ้านที่ใกล้ที่สุดใน Postgis 2.0 โดยใช้ GIST ดัชนี (<-> ฟังก์ชั่น)


25

ฉันพยายามใช้ฟังก์ชันใหม่ของ Postgis 2.0 <-> (Geometry Distance Centroid) เพื่อคำนวณสำหรับแต่ละแถวของตาราง (cosn1) ระยะทางของรูปหลายเหลี่ยมที่ใกล้เคียงที่สุดของชั้นเดียวกัน

ฉันพยายามใช้รหัสต่อไปนี้:

WITH index_query AS (
  SELECT g1.gid As ref_gid, ST_Distance(g1.the_geom,g2.the_geom) As ENN    
    FROM "cosn1" As g1, "cosn1" As g2   
    WHERE g1.gid <> g2.gid AND g1.class = g2.class
    ORDER BY g1.gid, g1.the_geom <-> g2.the_geom) 
SELECT DISTINCT ON (ref_gid) ref_gid, ENN 
    FROM index_query
ORDER BY ref_gid, ENN;

แต่ฉันก็ตระหนักถึงคำเตือน:

หมายเหตุ: ดัชนีจะเริ่มขึ้นก็ต่อเมื่อหนึ่งในรูปทรงเรขาคณิตเป็นค่าคงที่ (ไม่ใช่ในแบบสอบถามย่อย / cte) เช่น 'SRID = 3005; POINT (1011102 450541)' :: รูปทรงเรขาคณิตแทน a.geom

ความหมายที่ว่าจะไม่ใช้ดัชนีเลยและการสืบค้นจะใช้เวลาเกือบเหมือนเดิมก่อนการใช้:

SELECT DISTINCT ON(g1.gid)  g1.gid As ref_gid, ST_Distance(g1.the_geom,g2.the_geom) As ENN    
    FROM "cosn1" As g1, "cosn1" As g2   
    WHERE g1.gid <> g2.gid AND g1.class = g2.class
    ORDER BY g1.gid, ST_Distance(g1.the_geom,g2.the_geom)

ใครช่วยชี้วิธีแก้ปัญหาให้ฉันเพื่อปรับปรุงประสิทธิภาพการสืบค้นของฉันได้บ้าง

ขอบคุณมาก.


ยังไม่มีคำตอบคุณอาจต้องการถามเรื่องนี้ในรายชื่อผู้รับจดหมายของ PostGIS
GIS-Jonathan

ฉันทำไปแล้วแต่ยังไม่มีการตอบสนองใด ๆ
Alexandre Neto

3
คุณสามารถใช้ g1.gid> g2.gid ในส่วนคำสั่ง where ซึ่งจะลดจำนวนการคำนวณระยะทางที่คุณต้องทำ น่าเสียดายที่จนกว่าตัวดำเนินการ <-> จะทำงานโดยไม่มีค่าคงที่เราจะไม่เห็นการปรับปรุงความเร็วในแบบสอบถามชนิดนี้มากนัก
John Powell

จอห์นฉันจำเป็นต้องเก็บ gids ทั้งหมดแม้แต่ที่ทำซ้ำเพราะฉันจำเป็นต้องอัพเดต EEN สำหรับรูปหลายเหลี่ยมแต่ละอันในตาราง "cosn1" ของฉัน แต่สิ่งที่คุณพูดทำให้ฉันมีความคิด ฉันทำได้ตามที่คุณบอกโดยใช้ g1.gid> g2.gis เพื่อลดการคำนวณระยะทาง แต่ให้ g1.gid และ g2.gid เป็นผลลัพธ์ หลังจากนั้นฉันสามารถรวมแบบสอบถามย่อยสองชุดได้ (อันที่มี g1.gis เป็น gid และอีกอันกับ g2.gid) ขอบคุณ
Alexandre Neto

ฉันพบว่าทางออกที่เป็นไปได้ในการแก้ไขปัญหาคงที่คือการใช้ <-> ภายในฟังก์ชัน SQL โดยใช้ the_geom เป็นพารามิเตอร์ ฉันได้ทำการทดสอบบางอย่างและในบางกรณีมันเร็วกว่ามาก () แต่ในกรณีของฉันเนื่องจากระยะทางอยู่ในตารางเดียวกันการคำนวณระยะทางหลายครั้งจะถูกทำซ้ำในระหว่างกระบวนการทำให้ช้ากว่าการใช้การสอบถามโดยตรง
Alexandre Neto

คำตอบ:


2

Hum กำลังทำการทดสอบบางอย่างกับเครื่องของฉันฟังดูเหมือนว่าตัวดำเนินการ <-> นี้ทำงานไม่ถูกต้อง ฉันไม่แน่ใจว่าเป็นข้อผิดพลาด แต่รายงานระยะทางศูนย์บนรูปทรงเรขาคณิตที่ไม่ทับซ้อนกัน ไม่น่าสนใจใช่ไหม

แล้วการเพิ่มประสิทธิภาพการสืบค้น SQL แบบดั้งเดิมที่เหมาะสมล่ะ เนื่องจากผลลัพธ์ที่ไม่คาดคิดกับตัวดำเนินการ <-> ฉันจึงแทนที่ด้วย st_centroid ได้ผลลัพธ์ที่ดีกว่ามากในความเร็ว

หวังว่าความหมายกับ st_overlaps ยังคงเหมือนเดิม อย่างน้อยฉันก็เข้าใจจากเอกสารเกี่ยวกับ <->

จากเอกสารบน Postigs <->

สำหรับประเภทเรขาคณิตอื่น ๆ ระยะห่างระหว่างเซนทรอยด์บ็อกซ์จุดลอยตัวจะถูกส่งคืน

จากข้อมูลการทดสอบของฉันที่มีรูปหลายเหลี่ยม ~ 5.5k มีความเร็วเพิ่มขึ้นจาก ~ 1000 วินาทีถึง ~ 5 วินาทีโดยไม่มีการทำดัชนีเชิงพื้นที่

อย่างไรก็ตามทำไมใช้ DISTINCT ON เพื่อทำการจัดกลุ่ม? ฉันเห็นบางคนใช้ แต่ไม่มีกลุ่มโดยมีอยู่เพื่อกำจัดรายการที่ซ้ำกันหรือไม่

แบบสอบถามของคุณด้วยการเพิ่มประสิทธิภาพ SQL มาตรฐานโดยไม่มีข้อผิดพลาด st_centroid แนะนำ

select g1.gid, min( st_distance( g1.the_geom, g2.the_geom ) ) AS enn
FROM 
  "cosn1" AS g1, "cosn1" AS g2
WHERE
  g1.gid <> g2.gid
  AND g1.class = g2.class
  AND g1.the_geom && g2.the_geom
GROUP BY
  g1.gid

สุขสันต์วันหยุดคริสต์มาส!


ขออภัยคำตอบของคุณไม่สามารถแก้ปัญหาได้ ในความเป็นจริงมันเร็วกว่ามาก แต่ผลลัพธ์ไม่ถูกต้องเนื่องจากผลลัพธ์สุดท้ายถูกคำนวณโดยใช้เซนทรอยด์ของรูปหลายเหลี่ยมแทนที่จะเป็นรูปทรงเรขาคณิตที่แท้จริง <-> มีวัตถุประสงค์เพื่อเพิ่มประสิทธิภาพการค้นหาผู้สมัครไปยังเพื่อนบ้านที่ใกล้ที่สุด แต่ในที่สุดควรใช้รูปทรงเรขาคณิตที่แท้จริงในการคำนวณระยะทางกับผู้สมัครที่ดีที่สุด ฉันลองใช้ MIN \ GROUP BY แทน DISTINCT ON \ ORDER BY และดูเหมือนว่าจะช้ากว่า
Alexandre Neto

แต่คู่มือ postgis สำหรับโอเปอเรเตอร์ <-> ระบุว่าใช้เซนทรอยด์สำหรับรูปทรงเรขาคณิตที่ไม่ใช่จุด ดังนั้นทางออกของฉันจะให้ผลลัพธ์ที่คล้ายกัน ควรให้ผลลัพธ์เช่นเดียวกับข้อความค้นหายอดนิยมของคุณ โปรดตรวจสอบว่าผลลัพธ์ที่มีตัวดำเนินการ <-> นั้นถูกต้องเช่นกัน มันรายงานรูปทรงเรขาคณิตที่มีความยาวเป็นศูนย์จากข้อมูลการทดสอบของฉันดังนั้นผลลัพธ์ของมันอาจจะเสียและวิธีนี้ให้ข้อมูลที่แม่นยำยิ่งขึ้น หากคุณสามารถโพสต์ตัวอย่างบันทึกที่แสดงข้อผิดพลาดได้ที่เว็บไซต์ Pastie เราสามารถค้นพบข้อบกพร่องในการแก้ปัญหา
cavila

หากคุณตรวจสอบข้อความค้นหาของฉันตัวดำเนินการ <-> จะถูกใช้เพื่อสั่งซื้อผู้สมัครเท่านั้นผลลัพธ์สุดท้ายจะถูกคำนวณโดยใช้รูปทรงเรขาคณิตที่แท้จริง อย่างไรก็ตามอย่างที่ฉันได้พูดไปก่อนหน้านี้การเพิ่มประสิทธิภาพของ <-> นั้นใช้ได้กับคะแนนคงที่เท่านั้น นั่นคือคำถามเดิมของฉัน
Alexandre Neto

ดังนั้นคุณเห็นด้วยหรือไม่ว่าข้อความค้นหายอดนิยมไม่เท่ากับข้อความค้นหาด้านล่างหรือไม่ เนื่องจากคำสั่งซื้อจะเปลี่ยนแปลงเนื่องจากตัวดำเนินการ <-> จะ ORDER BY st_centroid และ st_distance จะให้ค่าที่แตกต่างกับคุณหรือไม่ คำสั่งซื้อที่แตกต่างกันสามารถนำข้อความค้นหาที่แตกต่างกันเป็นแถวแรกเพื่อส่งผ่าน DISTINCT ON clause ได้? ข้อความค้นหาที่ถูกต้องจะเป็นข้อความที่ต้องการการปรับปรุงความเร็วหรือไม่
cavila

ใช่แบบสอบถามแรกคือความตั้งใจที่จะปรับปรุงความเร็วที่ด้านล่าง และใช่มันอาจให้ผลลัพธ์ที่แตกต่างกันเล็กน้อยเนื่องจาก g1.geom <-> g2.geom ใช้ centroids และนั่นหมายความว่าแถวแรกอาจไม่ใกล้เคียง เพื่อให้มันใช้งานได้ฉันเชื่อว่าฉันจะต้อง จำกัด การเรียงลำดับตามข้อที่พูดถึงขีด จำกัด ที่ 10 แล้วแยกค่าที่แท้จริงของระยะทาง อาจใช้ <#> แทนก็ได้ซึ่งใช้กล่องขอบแทนเซนทรอยด์
Alexandre Neto
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.