คีย์ / ค่า Hstore แบบรวมและการสืบค้นเชิงพื้นที่ช้าเกินไปที่จะจัดการสารสกัด OSM ที่ใหญ่กว่า


13

ฉันพยายามคำนวณสถิติของข้อมูล OSM โดยใช้ PostgreSQL 9.3.5 และ PostGIS 2.1.4 ฉันเริ่มต้นด้วยสารสกัดบาวาเรียขนาดเล็กซึ่งฉันดาวน์โหลดจาก Geofabrik db schema เป็น API แบบปกติ 0.6 0.6 ข้อมูลจะถูกนำเข้าผ่านวิธีการถ่ายโอนข้อมูลไปยัง Postgres (โดยใช้สคริปต์ pgsnapshot_schema_0.6 * .sql ซึ่งมาพร้อมกับ osmosis) ทำการวิเคราะห์สูญญากาศด้วย

สิ่งเดียวที่ทำเองที่ฉันใช้อยู่คือตารางรูปหลายเหลี่ยมซึ่งมีมัลติโพลิกอนสำหรับความสัมพันธ์ด้านการดูแลระบบทั้งหมด เรขาคณิตของรูปหลายเหลี่ยมนั้นไม่ได้ทำให้ง่ายขึ้น แต่อย่างใด

สิ่งที่ฉันพยายามจะทำคือการนับจำนวนโหนดทั้งหมดที่อยู่ใน admin = 6 ขอบเขตของบาวาเรีย นี่คือแบบสอบถาม SQL ของฉัน:

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 ทำการวนลูปซ้อนกันและทำการสแกนโหนดทั้งหมดสำหรับทุก admin = 6 ขอบเขต FYI, บาวาเรียแบ่งออกเป็น 98 ผู้ดูแล = 6 รูปหลายเหลี่ยมและมีประมาณ 30 ล้านโหนดในสารสกัดบาวาเรีย

เป็นไปได้หรือไม่ที่จะหลีกเลี่ยงการดำเนินการค้นหาย่อยที่เหมาะสมและบอก Postgres ว่าควรสแกนโหนดทั้งหมดเพียงครั้งเดียว (เช่นโดยการเพิ่มตัวนับสำหรับรูปหลายเหลี่ยมที่สอดคล้องกันในชุดผลลัพธ์หรือโดยใช้คำแนะนำ)

แก้ไข:

1) ดัชนีเชิงพื้นที่มีอยู่บนโหนดบาวาเรีย:

CREATE INDEX idx_nodes_geom ON bavaria.nodes USING gist (geom);

2) แผนคิวรีมีลักษณะดังนี้:

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)

ฉันสร้างดัชนีสองรายการต่อไปนี้ แต่แผนแบบสอบถาม (และรันไทม์) ไม่เปลี่ยนแปลง

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 หรือไม่
30184

ใช่ฉันได้แก้ไขคำถามและให้ข้อมูลเกี่ยวกับดัชนีบนโหนดและแผนแบบสอบถาม
Alf Kortig

3
สองตัวเลือก 1 - เพิ่มดัชนีสำหรับแท็ก hstore 2 - แยกแท็กที่คุณใช้สำหรับการสืบค้น ( boundaryและadmin_level) ลงในคอลัมน์เพิ่มเติมบนตารางและใช้แท็กเหล่านั้นโดยตรง
BradHards

ดูการแก้ไข (3): ดัชนีสองตัวถูกเพิ่มเข้ามา แต่ไม่มีการเปลี่ยนแปลงใด ๆ กับแผนแบบสอบถามหรือรันไทม์
Alf Kortig

หลังจากการทดสอบฉันไม่แน่ใจอีกต่อไปว่าจะสร้างดัชนีที่ถูกต้องใน (3) หรือไม่ จนถึงตอนนี้ฉันสามารถสร้างดัชนีสำหรับ -> และ? ผู้ประกอบการ hstore อย่างไรก็ตามฉันใช้ @> ในข้อความค้นหาของฉัน
Alf Kortig

คำตอบ:


5

วิธีที่ดีที่สุดในการจัดทำดัชนีแท็ก hstore คือการใช้ดัชนี GIN หรือ GIST ซึ่งจากเอกสารสนับสนุน@>,?,? & และ? | โอเปอเรเตอร์คือค้นหาคีย์และคู่คีย์ / ค่า วิธีการของคุณในการใช้ฟังก์ชั่นเพื่อแยกแท็กสำหรับดัชนี B-tree นั้นสมเหตุสมผล แต่เนื่องจากคุณกำลังตรวจสอบคู่คีย์ / ค่าที่เฉพาะเจาะจงด้วยเช่นกันเครื่องวิเคราะห์จึงเลือกการสแกนตารางแบบเต็ม

ฉันไม่สามารถเข้าถึง bavaria.relpolygons แต่จากการสืบค้นที่คล้ายกันสำหรับ OSM UK เกี่ยวกับการ จำกัด ความเร็วและแท็ก Highway ฉันได้รับสิ่งนี้เพื่ออธิบายเกี่ยวกับแบบสอบถามต่อไปนี้:

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 ล้านแถวจะได้รับการสนับสนุน ดัชนีถูกสร้างด้วยวิ:

CREATE INDEX ix_ways_tags_gist ON ways USING gist (tags);

แม้ว่าฉันจะไม่สามารถตรวจสอบสภาพอวกาศของคุณได้ แต่ฉันเดาว่ามันน่าจะเลือกน้อยกว่า

WHERE relpoly.tags @> '"ขอบเขต" => "การดูแลระบบ", "admin_level" => "6"' :: hstore

และจะใช้สำหรับเงื่อนไขการตรวจสอบใหม่เท่านั้น

นอกจากนี้ยังมีนี้คำตอบที่ดีดังนั้นความแตกต่างระหว่างจินและจีดัชนี การค้นพบโดยทั่วไปคือดัชนีของ GIN ในขณะที่มีขนาดใหญ่ขึ้นและช้าลงเพื่อสร้าง

ขออภัยที่จะตอบช้ามาก แต่เมื่อเร็ว ๆ นี้ฉันกำลังทำงานคล้ายกับ OSM และ hstore และพบว่าไม่เพียง แต่ฉันเคยติดดาวคำถามนี้ แต่ตอนนี้ฉันสามารถตอบได้: D

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