PostGIS ST_Intersects में प्रदर्शन की समस्या को कैसे ठीक करें?


9

मैं पोस्टगिस में नौसिखिया हूं और मुझे क्वेरी के प्रदर्शन में समस्या है।

यह मेरा प्रश्न है:

SELECT DISTINCT ON (userid) userid ,ST_AsText(position), timestamp  
FROM table1 
WHERE ST_Intersects ( ST_GeomFromText('a multiypolygon geom goes here',4326),position) 
ORDER BY userid, timestamp desc

और समस्या यह है कि मेरा मल्टीप्लगॉन में बहुत बड़े बहुभुज (शब्द डॉक्टर में 600 पृष्ठ लंबे!) शामिल हैं और इसे निष्पादित करने में 2 घंटे से अधिक समय लगा!

क्या मेरी क्वेरी को अनुकूलित करने या किसी अन्य तरीके का उपयोग करने का कोई तरीका है?

कृपया आपकी मदद की बहुत सराहना की है!

जवाबों:


8

आपको क्या करना चाहिए अपने एकल बहुभुज को एक एकल बहुभुज (ST_Dump के साथ) के रूप में एक तालिका में रखा जाए और उस पर एक सूचकांक रखा जाए। कुछ इस तरह:

CREATE TABLE big_polygon as
SELECT (ST_Dump( ST_GeomFromText('a multiypolygon geom goes here',4326))).geom as geom;

-- It is always great to put a primary key on the table
ALTER table big_polygon ADD Column gid serial PRIMARY KEY;

-- Create the index
CREATE INDEX idx_big_polygon_geom
on big_polygon
USING gist(geom);

-- To give the database some information about how the index looks
analyze big_polygon;

-- Then you go:
SELECT DISTINCT ON (userid) userid ,ST_AsText(position), timestamp  
FROM table1, big polygon WHERE ST_Intersects ( big_polygon.geom,position) 
ORDER BY userid, timestamp desc;

यह कई कारणों से तेजी से होना चाहिए।


इस बेहतरीन उत्तर के लिए धन्यवाद Nicklas। क्षमा करें, मैंने यह उल्लेख करने में चूक की कि मेरे पास एक से अधिक बहुभुज हैं और वे पहले से ही सूचकांक वाली तालिका में संग्रहीत हैं। लेकिन मुझे लगता है कि जियोम डेटा सीधे उपलब्ध होगा। हालाँकि, मैं आपके सुझाव के तरीके की कोशिश करता हूँ, लेकिन अभी भी बहुत समय लग रहा है! कोई और सुझाव?
सारा

@ तारा। ठीक है, इसलिए आपने मल्टी जिओमेट्री को एकल ज्यामितीय में विभाजित करने का प्रयास किया जैसा कि मैंने ST_Dump के साथ सुझाव दिया है?
निकलस एवेन

हम कितने उपयोगकर्ता पदों के बारे में बात कर रहे हैं? कितने बड़े बहुभुज? आपको बड़े_पॉलिगन्स_टेबल से सेलेक्ट ST_npoint (जियोम) से क्या मिलता है?;
निकोलस एवेन

क्षमा करें मेरे बुरे, मुझे आपके बारे में और अधिक स्पष्ट करने के लिए मेरी तालिकाओं के बारे में अधिक बताएं: मेरे पास तालिका 1 है जिसमें एक भू स्तंभ शामिल है जिसमें लगभग 230 पंक्तियाँ हैं और प्रत्येक पंक्ति में एक बहुभुज है (वे देशों का प्रतिनिधित्व करते हैं ताकि वे आकार में भिन्न हों) , और the_geom कर्नल में अनुक्रमणिका है। Table2 जिसमें पोजिशन कॉलम (पॉइंट्स), टाइमस्टैम्प, यूजरिड और आईडी (pk) और 3 इंडेक्स बनाए गए हैं (स्थिति, टाइमस्टैम्प, यूजरआईडी)। यह टेबल 103496003 पंक्तियों के बारे में बहुत बड़ी है। ST_npoints की Tha अधिकतम संख्या 1440430 है और न्यूनतम संख्या है। 16. मुझे खेद है अगर मैंने आपको भ्रमित किया है लेकिन मुझे आपकी मदद की ज़रूरत है! साभार
सारा

2

यह निर्भर करता है कि आपको किस प्रकार की गुणवत्ता - सटीकता की आवश्यकता है। आप स्पष्ट रूप से बहुभुजों को सरल बना सकते हैं: http://postgis.net/docs/ST_Simplify.html

अपने जीआईएस एप्लिकेशन के विकास के दौरान मैंने अक्सर क्या किया, डेटा को कम करने के सबसे अच्छे तरीके के बारे में सोचना था। उदाहरण के लिए। उदाहरण के लिए सीमा बॉक्स के भीतर बहुभुज का चयन करें। - ज़ूमलेवल के आधार पर आपको अल्ट्रा सटीक परिणाम (st_simplify) की आवश्यकता नहीं है ...

आशा है कि आप थोड़ा मदद की!


आपकी त्वरित प्रतिक्रिया के लिए धन्यवाद मार्टिन। मेरी समस्या यह है कि मुझे परिणाम की आवश्यकता बहुत सटीक है, इसलिए मुझे लगता है कि यह फ़ंक्शन मुझे यहां मदद नहीं करेगा! लेकिन सुझाव के लिए धन्यवाद
सारा

0

आपके पोस्टग्रेज और / या sql विशेषज्ञता के आधार पर आपके पास कई विकल्प हैं:

  1. यदि आप किसी विशेष अड़चन को मार रहे हैं, तो यह पता लगाने के लिए EXPLAIN कमांड के माध्यम से क्वेरी का विश्लेषण करें । चेतावनी: कभी-कभी EXPLAIN के आउटपुट को समझना मुश्किल हो सकता है

  2. यदि आप अपेक्षा करते हैं कि तालिका 1 में जियोमेट्री का अधिकांश या महत्वपूर्ण भाग मल्टीप्लायगोन को नहीं काटता है, तो आप एक सरल बहुभुज के खिलाफ प्रारंभिक स्थिति को लागू करने की कोशिश कर सकते हैं (अर्थात छोटे टुकड़ों में मल्टीप्लगॉन को तोड़कर) और फिर केवल भारी मल्टीप्लगॉन चौराहे पर चलाएं। उन परिणामों। एक उदाहरण के लिए नीचे देखें।

  3. यदि और केवल यदि सीपीयू टोंटी है (यानी सर्वर अटक कंप्यूटिंग चौराहों है) मैं dully आप एक बड़ा, तेज, और अधिक शक्तिशाली सीपीयू पाने का सुझाव देते हैं या अमेज़न के EC2 बंद एक बार की उच्च सीपीयू उदाहरण किराए पर लेने और इसे नष्ट जब आप कर रहे हैं किया हुआ

आइटम 2 के लिए उदाहरण क्वेरी:

SELECT DISTINCT ON (st1.userid) st1.userid ,ST_AsText(st1.position), st1.timestamp  
FROM (
    select userid, position, timestamp from table1 
    WHERE ST_Intersects ( YOUR_MULTIPOL_BOUNDS_HERE,position)
) as st1 
WHERE ST_Intersects ( ST_GeomFromText('a multiypolygon geom goes     here',4326),st1.position) 
ORDER BY st1.userid, st1.timestamp desc

प्रदर्शन में सुधार करने के लिए आप एक तालिका के रूप में subselect st1 को अस्थायी रूप से उत्प्रेरित कर सकते हैं ताकि आप इसे अनुक्रमित कर सकें।

@Nicklas टिप्पणियों में इंगित करना सही है जो सुझाव 2 के लिए उदाहरण के लिए मदद नहीं करनी चाहिए। वह सही है, लेकिन मुझे लगता है कि मैं (आंशिक रूप से) भी सही हूं।

वास्तव में ऐसा लगता है कि एक बहुत ही समान प्रश्न पूछा गया था (और उत्तर दिया) अभी पिछले नवंबर में पोस्टगिस एमएल:

http://postgis.refractions.net/pipermail/postgis-users/2011-November/031344.html

और पता चलता है कि वास्तव में बहुभुज को तोड़ने का सुझाव है ताकि सूचकांक सबसे प्रभावी रूप से झूठे चौराहों को छान सके जो अन्यथा एक सरल सीमा जांच द्वारा ट्रिगर हो जाएंगे।


सुझाव 2 को मदद नहीं करनी चाहिए क्योंकि यह वही है जो सूचकांक कर रहा है। ताकि निर्माण एक बार फिर से वही हो।
निकोलस एवेन

@ NicklasAvén तुम सही हो, मैंने जवाब में संशोधन किया
unicoletti

0

का उपयोग करते हुए ST_SubDivide()

Postgis के संस्करण 2.2 के लिए, आप उपयोग कर सकते हैं ST_SubDivide

ST_Subdivide - ज्यामिति का एक सेट लौटाता है जहाँ सेट में कोई भी ज्यामिति निर्दिष्ट संख्याओं से अधिक नहीं होती है।

setof geometry ST_Subdivide(geometry geom, integer max_vertices=256);

आप भी कर सकते हैं

  • एक अस्थायी तालिका का उपयोग करें
  • एक अनुक्रमणिका

यहाँ हम ST_SubDivideबहुभुज को 10 या उससे कम लम्बाई में बहुभुज को तोड़ने के लिए उपयोग करते हैं।

CREATE TEMP TABLE divided AS
SELECT ST_SubDivide(bigmultipolygon,10)::geometery AS t(geom);

CREATE INDEX divided_idx ON divided USING gist(geom);

फिर

SELECT DISTINCT ON (userid) userid ,ST_AsText(position), timestamp  
FROM table1
JOIN divided AS d
  ON ST_Intersects( d.geom, position )
ORDER BY userid, timestamp desc;

उपरोक्त मत करो, यह गोलाई त्रुटियों का परिचय देता है

सामान्य ट्यूनिंग

डॉक्स में प्रदर्शन टिप्स नामक अनुभाग भी देखें । सुनिश्चित करें कि आप उचित रूप से देखते हैं। max_parallel_workers_per_gatherसमानांतरकरण (वर्तमान में बंद चूक) का लाभ उठाने के लिए ऊपर उठाने पर विचार करें ।

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