संयुक्त Hstore कुंजी / मूल्य और स्थानिक क्वेरी बड़े OSM अर्क को संभालने के लिए बहुत धीमी है


13

मैं PostgreSQL 9.3.5 और PostGIS 2.1.4 का उपयोग करके OSM डेटा के लिए कुछ आंकड़ों की गणना करने की कोशिश कर रहा हूं। मैंने एक छोटी बावरिया अर्क के साथ शुरुआत की जिसे मैंने जियोफैब्रिक से डाउनलोड किया। डीबी स्कीमा सामान्य एपीआई 0.6 स्कीमा है, डेटा को पोस्टग्रेज में डंप दृष्टिकोण (pgsnapshot_schema_0.6 .sql स्क्रिप्ट जो परासरण के साथ आता है) के माध्यम से आयात किया गया था। ANALYZE VACUUM का प्रदर्शन भी किया गया।

एकमात्र कस्टम मेड चीज़ जो मैं उपयोग कर रहा हूं वह एक बहुभुज तालिका है जिसमें सभी प्रशासनिक सीमा संबंधों के लिए बहुपरत शामिल हैं। बहुभुज ज्यामिति को किसी भी तरह से सरल नहीं किया गया था।

अब मैं जो कुछ हासिल करने की कोशिश कर रहा हूं, वह सभी नोड्स को गिन रहा है जो कि व्यवस्थापक के अंदर हैं = बवेरिया की 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 नेस्टेड लूप जॉइन कर रहा है और हर एडमिन = 6 बाउंड्री के लिए सभी नोड्स पर स्कैन करता है। FYI करें, बवेरिया को 98 व्यवस्थापक = 6 बहुभुजों में विभाजित किया गया है और बावरिया अर्क में लगभग 30 मिलियन नोड हैं।

क्या यह उप-इष्टतम क्वेरी निष्पादन से बचने और पोस्टग्रेज को यह बताने के लिए संभव है कि यह केवल एक बार सभी नोड्स को स्कैन करे (जैसे, परिणाम सेट में संबंधित बहुभुज के लिए एक काउंटर बढ़ाकर या संकेत का उपयोग करके)?

संपादित करें:

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 में स्थानिक सूचकांक है?
user30184

हां, मैंने सवाल संपादित किया है और नोड्स पर सूचकांक और क्वेरी योजना के बारे में जानकारी प्रदान की है
अल्फ कोर्तिग

3
दो विकल्प। 1 - hstore टैग के लिए एक इंडेक्स जोड़ें। 2 - आपके क्वेरी ( boundaryऔर admin_level) के लिए आपके द्वारा उपयोग किए जा रहे टैग्स को टेबल पर मौजूद अतिरिक्त कॉलम में निकालें , और सीधे उन का उपयोग करें।
ब्रैडहार्ड्स

संपादन देखें (3): दो इंडेक्स जोड़े गए थे, लेकिन क्वेरी प्लान में कोई बदलाव नहीं किया गया था और न ही रनटाइम के लिए।
अल्फ कोर्टिग

कुछ परीक्षण के बाद मुझे यकीन नहीं हो रहा है कि क्या मैंने (3) में सही इंडेक्स बनाया है। अब तक, मैं -> और के लिए एक इंडेक्स बनाने में कामयाब रहा? hstore ऑपरेटर्स। हालांकि, मैं उपयोग कर रहा हूँ @> मेरी क्वेरी में
Alf Kortig

जवाबों:


5

Hstore टैग को इंडेक्स करने का सबसे अच्छा तरीका GIN या GIST इंडेक्स का उपयोग करना है, जो डॉक्स से @ @?;?; और? को सपोर्ट करता है ऑपरेटर , जो कुंजी और कुंजी / मान जोड़े पर खोज करता है। आप बी-ट्री इंडेक्स के लिए टैग निकालने के लिए एक फ़ंक्शन का उपयोग करने का दृष्टिकोण उचित है, लेकिन क्योंकि आप विशिष्ट कुंजी / मूल्य जोड़े के लिए भी जांच कर रहे हैं, विश्लेषक ने एक पूर्ण तालिका स्कैन चुना है।

मेरे पास bavaria.relpolygons की पहुंच नहीं है, लेकिन गति सीमा और राजमार्ग टैग पर OSM यूके के लिए एक समान क्वेरी के आधार पर, मुझे निम्नलिखित क्वेरी पर मेरे स्पष्टीकरण के लिए यह मिलता है:

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

जबकि मैं आपको स्थानिक स्थिति की जांच नहीं कर सकता, मुझे लगता है कि यह कम से कम चयनात्मक है

कहाँ relpoly.tags @> "सीमा" => "प्रशासनिक", "admin_level" => "6" ':: hstore।

और इसलिए केवल एक रीचेक स्थिति के लिए उपयोग किया जाएगा।

GIN और GIST इंडेक्स के बीच अंतर पर भी यह बहुत अच्छा जवाब है । सामान्य खोज यह है कि GIN अनुक्रमित जबकि निर्माण करने के लिए बड़ा और धीमा, पाठ पुनर्प्राप्ति समस्याओं पर बहुत तेज है।

इतनी देर से जवाब देने के लिए क्षमा करें, लेकिन मैंने हाल ही में OSM और hstore पर इसी तरह का काम किया है, और पता चला है कि न केवल मैंने एक बार इस प्रश्न को घूर लिया था, लेकिन अब मैं इसका उत्तर दे सकता हूं: डी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.