पोस्टगिस में आर्कगिस जैसी गति प्राप्त करना


62

मैं अब एक वर्ष के 3/4 के लिए Postgis 2.0 का उपयोग कर रहा हूं और जब मैं वास्तव में इसका उपयोग कर रहा हूं, अत्यधिक क्वेरी प्रसंस्करण समय ने इसे मूल रूप से मेरे उपयोग के मामले के लिए अनुपयोगी बना दिया है।

मैं म्युनिसिपल डेटासेट पर भारी जियोप्रोसेसिंग करता हूं, जिसमें अक्सर कई हज़ारों मल्टीप्लगॉन होते हैं। ये मल्टीप्लगॉन कभी-कभी बहुत अनियमित रूप से आकार लेते हैं और 4 अंक से 78,000 अंक प्रति मल्टीप्लगोन में भिन्न हो सकते हैं।

उदाहरण के लिए, जब मैं ३२ ९, १५२ मल्टीप्लोगों वाले पार्सल डेटासेट को ५२५ मल्टीप्लगॉन वाले क्षेत्राधिकार डेटासेट के साथ जोड़ देता हूं, तो मुझे कुल प्राप्त समय के लिए निम्नलिखित आँकड़े मिलते हैं:

ArcGIS 10.0 (on same host with windows 7 OS): 3 minutes
Postgis:56 minutes (not including geometry pre-processing queries)

दूसरे शब्दों में, पोस्टगिस में इस चौराहे को आर्कगिस की तुलना में करने के लिए 1500% अधिक समय की आवश्यकता होती है - और यह मेरे अधिक सरल प्रश्नों में से एक है!

माना जाता है कि आर्कजीआईएस तेजी से चलने के कारणों में से एक बेहतर सूचकांक है। कुछ प्रोग्रामर्स ने हाल ही में पता लगाया कि ये इंडेक्स कैसे काम करते हैं और मैं सोच रहा हूं कि क्या किसी को पता है कि इन इंडेक्स को पोस्टगिस में कैसे बनाया जाए (या उन टेबल्स का निर्माण करें जो इंडेक्स की नकल करेंगे)। शायद इससे पोस्टगिस में अधिकांश गति मुद्दों का समाधान हो जाएगा। मैं केवल उम्मीद कर सकता हूं कि कोई रास्ता होना चाहिए, खासकर जब से आर्कगिस केवल 4 जीबी रैम का उपयोग कर सकता है, जबकि मैं अपने पोस्टगिस सर्वर के लिए 4 गुना तक उपयोग कर सकता हूं!

बेशक कई कारण हैं पोस्टगिस धीरे-धीरे चल सकते हैं, इसलिए मैं अपने सिस्टम चश्मे का एक विस्तृत संस्करण प्रदान करूंगा:

Machine: Dell XPS 8300 
Processor: i7-2600 CPU @ 3.40 GHz 3.40 GHz 
Memory: Total Memory 16.0 GB (10.0 GB on virtual machine)

Platform: Ubuntu Server 12.04 Virtual Box VM

Potgres Version: 9.1.4
Postgis Version: POSTGIS="2.0.1 r9979" GEOS="3.3.5-CAPI-1.7.5" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.9.1, released 2012/05/15" LIBXML="2.7.8" LIBJSON="UNKNOWN" TOPOLOGY RASTER

मैं पूरी स्थापना प्रक्रिया का भी विवरण देता हूं, जिसका उपयोग मैंने स्वयं वीएम के निर्माण सहित पोस्टगिस को स्थापित करने के लिए किया था

मैंने डिफॉल्ट फाइल में डिफ़ॉल्ट मेमोरी को 24MB से 6 जीबी तक बढ़ा दिया और पोस्टग्रेज को चलाने की अनुमति देने के लिए निम्न कमांड्स चलाए:

sudo sysctl -w kernel.shmmax=7516192768 (I know this setting is deleted every time you restart the OS)
sudo /etc/init.d/postgresql restart

जहां तक ​​मैं बता सकता हूं कि यह प्रदर्शन के मामले में बिल्कुल ध्यान देने योग्य है।

यहाँ इस परीक्षण के लिए मेरे द्वारा उपयोग किए गए डेटा के लिंक दिए गए हैं:

  1. पार्सल: tcad_parcels_06142012.shp.zip से ऑस्टिन, TX के सिटी
  2. न्यायालय: ऑस्टिन, TX के शहर से क्षेत्राधिकार की सीमाएँ

डेटा को संसाधित करने के लिए मैंने यहां कदम उठाए हैं:

ArcGIS

  1. ArcMap में डेटासेट जोड़ें
  2. केंद्रीय टेक्सास फीट के लिए समन्वय प्रणाली सेट करें (श्रीड 2277)
  3. ड्रॉपडाउन मेनू से चौराहे उपकरण का उपयोग करें

PostGIS

आयात पार्सल का उपयोग कर:

shp2pgsql -c -s 2277 -D -i -I -W UTF-8 "tcad_parcels_06142012.shp" "public"."tcad_parcels_06142012" |psql -d postgis_testing -U postgres -h local_ip -p 5432

आयात अधिकार क्षेत्र का उपयोग कर:

shp2pgsql -c -s 2277 -D -i -I -W UTF-8 "jurisdictions.shp" "public"."jurisdictions" |psql -d postgis_testing -U postgres -h local_ip -p 5432

पार्सल में साफ अवैध ज्यामिति:

DROP TABLE IF EXISTS valid_parcels;
CREATE TABLE valid_parcels(
  gid serial PRIMARY KEY,
  orig_gid integer,
  geom geometry(multipolygon,2277)
);
CREATE INDEX ON valid_parcels USING gist (geom);
INSERT INTO valid_parcels(orig_gid,geom)
  SELECT 
    gid 
    orig_gid,
    st_multi(st_makevalid(geom)) 
  FROM 
    tcad_parcels_06142012;
CLUSTER valid_parcels USING valid_parcels_geom_idx;

क्षेत्राधिकार में साफ अवैध ज्यामिति:

DROP TABLE IF EXISTS valid_jurisdictions;
CREATE TABLE valid_jurisdictions(
  gid serial PRIMARY KEY,
  orig_gid integer,
  geom geometry(multipolygon,2277)
);
CREATE INDEX ON valid_jurisdictions USING gist (geom);
INSERT INTO valid_jurisdictions(orig_gid,geom)
  SELECT 
    gid 
    orig_gid,
    st_multi(st_makevalid(geom)) 
  FROM 
    jurisdictions;
CLUSTER valid_jurisdictions USING valid_jurisdictions_geom_idx;

क्लस्टर चलाएँ:

cluster;

वैक्यूम विश्लेषण चलाएं:

vacuum analyze;

साफ तालिकाओं पर प्रतिच्छेदन करें:

CREATE TABLE parcel_jurisdictions(
  gid serial primary key,
  parcel_gid integer,
  jurisdiction_gid integer,
  isect_geom geometry(multipolygon,2277)
);
CREATE INDEX ON parcel_jurisdictions using gist (isect_geom);

INSERT INTO parcel_jurisdictions(parcel_gid,jurisdiction_gid,isect_geom)
  SELECT
    a.orig_gid parcel_gid,
    b.orig_gid jurisdiction_gid,
    st_multi(st_intersection(a.geom,b.geom))
  FROM
    valid_parcels a, valid_jurisdictions b
  WHERE
    st_intersects(a.geom,b.geom);

व्याख्या चौराहे की क्वेरी का विश्लेषण करें:

Total runtime: 3446860.731 ms
        Index Cond: (geom && b.geom)
  ->  Index Scan using valid_parcels_geom_idx on valid_parcels a  (cost=0.00..11.66 rows=2 width=1592) (actual time=0.030..4.596 rows=1366 loops=525)
  ->  Seq Scan on valid_jurisdictions b  (cost=0.00..113.25 rows=525 width=22621) (actual time=0.009..0.755 rows=525 loops=1)
Nested Loop  (cost=0.00..61428.74 rows=217501 width=24213) (actual time=2.625..3445946.889 rows=329152 loops=1)
  Join Filter: _st_intersects(a.geom, b.geom)

मैंने जो कुछ भी पढ़ा है, उससे मेरा चौराहा क्वेरी कुशल है और मुझे पूरी तरह से पता नहीं है कि मैं क्वेरी के लिए गलत ज्यामिति पर 56 मिनट लेने के लिए क्या गलत कर रहा हूं!


2
पोस्टगिस में चीजों को गति देने के लिए एक बाउंडिंग बॉक्स चौराहे की जांच को जोड़ना एक सामान्य मुहावरा है। अपने WHERE क्लॉज़ में 'और a.geom && b.geom' को जोड़ने का प्रयास करें और देखें कि इससे कितना फर्क पड़ता है।
शॉन

2
st_intersects () पोस्टगिस 2.x में किसी भी चौराहे का परीक्षण करने से पहले एक बाउंडिंग बॉक्स क्वेरी को शामिल करता है ताकि दुर्भाग्य से यह आपके समय की बचत न करे।
THX1138

1
क्या आप EXPLAIN ANALYZE का उपयोग करके आपको क्वेरी चला सकते हैं और परिणाम पोस्ट कर सकते हैं
Nathan W

1
आपको यह भी पता होना चाहिए कि आप पोस्टगिस बनाम आर्कगिस पर अलग-अलग डेटा सेट चला रहे हैं क्योंकि आप कहते हैं कि आप नेक्स को स्वीकार करने के लिए उन्हें वैध बनाने के लिए नेक्सस करते हैं।
निकलस एवीएन

2
क्या इसे देखने के लिए डेटा सेट प्राप्त करना संभव है?
निकलैस एवन

जवाबों:


87

अलग दृष्टिकोण। यह जानकर कि दर्द ST_Intersection में है, और यह सच / गलत परीक्षण तेज़ हैं, चौराहे से गुजरने वाली ज्यामिति की मात्रा को कम करने की कोशिश कर चीजों को गति दे सकता है। उदाहरण के लिए, पार्सल जो पूरी तरह से एक अधिकार क्षेत्र में समाहित किए गए हैं, उन्हें क्लिप करने की आवश्यकता नहीं है, लेकिन ST_Intersection अभी भी किसी भी नए ज्यामिति को उत्पन्न करने की आवश्यकता नहीं है, यह महसूस करने से पहले चौराहे के उपरिशायी हिस्से के निर्माण की परेशानी में जाएंगे। तो यह

INSERT INTO parcel_jurisdictions(parcel_gid,jurisdiction_gid,isect_geom)
SELECT
  a.orig_gid AS parcel_gid,
  b.orig_gid AS jurisdiction_gid,

  st_multi(st_intersection(a.geom,b.geom)) AS geom
FROM
  valid_parcels a, valid_jurisdictions b
WHERE
  st_intersects(a.geom, b.geom) and not st_within(a.geom, b.geom)
UNION ALL
SELECT
  a.orig_gid AS parcel_gid,
  b.orig_gid AS jurisdiction_gid,
  a.geom AS geom
FROM
  valid_parcels a, valid_jurisdictions b
WHERE
  st_within(a.geom, b.geom);

या टसर भी

INSERT INTO parcel_jurisdictions(parcel_gid,jurisdiction_gid,isect_geom)
SELECT
  a.orig_gid AS parcel_gid,
  b.orig_gid AS jurisdiction_gid,
  CASE 
     WHEN ST_Within(a.geom,b.geom) 
     THEN a.geom
     ELSE ST_Multi(ST_Intersection(a.geom,b.geom)) 
  END AS geom
FROM valid_parcels a
JOIN valid_jurisdictions b
ON ST_Intersects(a.geom, b.geom)

यूनिअन से भी तेज w / o हो सकता है।


13
धन्यवाद कि मुझे नीचे, 3.63 मिनट के लिए हो जाता है! मैंने कभी नहीं सोचा होगा कि एक संघ तेजी से होगा। यह उत्तर वास्तव में मुझे उस तरह से पुनर्विचार करने के लिए जा रहा है जिस तरह से मैं अभी से प्रश्न करता हूं।
THX1138

2
यह बहुत अच्छा है। मेरे पास काम का एक मामला था जहाँ मेरी st_intersection क्वेरी 30mins + ली गई थी और अब मुझे पता है कि मैं इससे कैसे बच सकता हूँ :)
Nathan W

1
इस सवाल ने मुझे Postgis सीखा! मैं आज अच्छी तरह से सोएगा पोस्टगिस को कंधे से कंधा मिलाकर आर्कगिस :-)
विआनयन

2
मार्टिन डेविस से एक और वृद्धि, आप "इन या आउट" कर सकते हैं? मामले में एक मामले का उपयोग करते हुए चयन करें और इस तरह से बचने के लिए सवाल करें।
पॉल रैमसे

2
UNIONदो प्रश्नों से डुप्लिकेट पंक्तियों को समाप्त करता है, लेकिन इन दो प्रश्नों की उनके परिणाम सेट में समान पंक्ति नहीं हो सकती है। इसलिए UNION ALL, जो डुप्लिकेट चेक को छोड़ देता है, यहां उचित होगा। (मैं UNIONइतना उपयोग नहीं करता हूं , लेकिन मैं आमतौर पर पाता हूं कि मैं जो समय करता हूं, UNION ALL
उसमें

4

यदि आप "st_multi(st_intersection(a.geom,b.geom))"भाग को छोड़ देते हैं तो क्या होगा ?

क्या नीचे की क्वेरी का अर्थ इसके बिना समान नहीं है? मैंने इसे आपके द्वारा प्रदान किए गए डेटा पर चलाया।

INSERT INTO parcel_jurisdictions(parcel_gid,jurisdiction_gid,isect_geom)
  SELECT
    a.orig_gid parcel_gid,
    b.orig_gid jurisdiction_gid,
    a.geom
  FROM
    valid_parcels a, valid_jurisdictions b
  WHERE
    st_intersects(a.geom,b.geom);

विन्यास

Processor: AMD Athlon II X4 635 2.9 GHz 
Memory: 4 GB
Platform: Windows 7 Professional
Potgres Version: 8.4
Postgis Version: "POSTGIS="2.0.1 r9979" GEOS="3.3.5-CAPI-1.7.5" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.9.1, released 2012/05/15" LIBXML="2.7.8" LIBJSON="UNKNOWN" TOPOLOGY RASTER"

परिणामों का विश्लेषण करें

"Nested Loop  (cost=0.00..7505.18 rows=217489 width=1580) (actual time=1.994..248405.616 rows=329150 loops=1)"
"  Join Filter: _st_intersects(a.geom, b.geom)"
"  ->  Seq Scan on valid_jurisdictions b  (cost=0.00..37.25 rows=525 width=22621) (actual time=0.054..1.732 rows=525 loops=1)"
"  ->  Index Scan using valid_parcels_index on valid_parcels a  (cost=0.00..11.63 rows=2 width=1576) (actual time=0.068..6.423 rows=1366 loops=525)"
"        Index Cond: (a.geom && b.geom)"
"Total runtime: 280087.497 ms"

नहीं, वह परिणामी प्रतिच्छेदन बहुभुज चाहता है, लेकिन आपकी क्वेरी बहुत अच्छी तरह से प्रदर्शित करती है कि सभी दर्द चौराहे की पीढ़ी में हैं, क्वेरी के द्विआधारी सच / झूठे परीक्षण भाग में नहीं। और यह काफी अपेक्षित है, क्योंकि सही / गलत कोड अत्यधिक अनुकूलित है जबकि चौराहा पीढ़ी नहीं है।
पॉल रैमसे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.