ฉันพยายามคำนวณสถิติของข้อมูล 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;
boundary
และadmin_level
) ลงในคอลัมน์เพิ่มเติมบนตารางและใช้แท็กเหล่านั้นโดยตรง