मुझे कितनी तेजी से PostGIS से अच्छी तरह से फॉर्मेट किए गए पते की उम्मीद करनी चाहिए?
मैंने PostgreSQL 9.3.7 और PostGIS 2.1.7 को स्थापित किया है, राष्ट्र डेटा और सभी राज्यों के डेटा को लोड किया है लेकिन मैंने अनुमान के मुकाबले जियोकोडिंग को बहुत धीमा पाया है। क्या मैंने अपनी अपेक्षाएँ बहुत ऊँची कर दी हैं? मुझे प्रति सेकंड औसतन 3 व्यक्तिगत जियोकोड मिल रहे हैं। मुझे लगभग 5 मिलियन करने की आवश्यकता है और मैं इसके लिए तीन सप्ताह इंतजार नहीं करना चाहता।
यह विशाल आर मैट्रिस के प्रसंस्करण के लिए एक आभासी मशीन है और मैंने इस डेटाबेस को किनारे पर स्थापित किया है ताकि कॉन्फ़िगरेशन थोड़ा नासमझ दिखे। यदि VM के कॉन्फ़िगरेशन में एक बड़ा परिवर्तन मदद करेगा, तो मैं कॉन्फ़िगरेशन को बदल सकता हूं।
हार्डवेयर चश्मा
मेमोरी: 65 जीबी प्रोसेसर: 6
lscpu
मुझे यह देता है:
# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 6
On-line CPU(s) list: 0-5
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 6
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 58
Stepping: 0
CPU MHz: 2400.000
BogoMIPS: 4800.00
Hypervisor vendor: VMware
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 30720K
NUMA node0 CPU(s): 0-5
ओएस सेंटोस है, uname -rv
यह देता है:
# uname -rv
2.6.32-504.16.2.el6.x86_64 #1 SMP Wed Apr 22 06:48:29 UTC 2015
Postgresql config
> select version()
"PostgreSQL 9.3.7 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11), 64-bit"
> select PostGIS_Full_version()
POSTGIS="2.1.7 r13414" GEOS="3.4.2-CAPI-1.8.2 r3921" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.9.2, released 2012/10/08" LIBXML="2.7.6" LIBJSON="UNKNOWN" TOPOLOGY RASTER"
प्रश्नों के इन प्रकार के लिए पिछले सुझाव के आधार पर मैंने बढ़ाकर shared_buffers
में postgresql.conf
उपलब्ध रैम और राम का 1/2 के लिए प्रभावी कैश आकार का 1/4 के बारे में करने के लिए फ़ाइल:
shared_buffers = 16096MB
effective_cache_size = 31765MB
मेरे पास installed_missing_indexes()
और (कुछ तालिकाओं में डुप्लिकेट आवेषणों को हल करने के बाद) कोई त्रुटि नहीं है।
जियोकोडिंग SQL उदाहरण # 1 (बैच) ~ औसत समय 2.8 / सेकंड है
मैं http://postgis.net/docs/Geocode.html से उदाहरण का अनुसरण कर रहा हूं , जिससे मुझे जियोकोड से पता रखने वाली एक तालिका बनाई गई है, और फिर एक एसक्यूएल किया जा रहा है UPDATE
:
UPDATE addresses_to_geocode
SET (rating, longitude, latitude,geo)
= ( COALESCE((g.geom).rating,-1),
ST_X((g.geom).geomout)::numeric(8,5),
ST_Y((g.geom).geomout)::numeric(8,5),
geo )
FROM (SELECT "PatientId" as PatientId
FROM addresses_to_geocode
WHERE "rating" IS NULL ORDER BY PatientId LIMIT 1000) As a
LEFT JOIN (SELECT "PatientId" as PatientId, (geocode("Address",1)) As geom
FROM addresses_to_geocode As ag
WHERE ag.rating IS NULL ORDER BY PatientId LIMIT 1000) As g ON a.PatientId = g.PatientId
WHERE a.PatientId = addresses_to_geocode."PatientId";
मैं 1000 से ऊपर के बैच आकार का उपयोग कर रहा हूं और यह 337.70 सेकंड में लौटता है। यह छोटे बैचों के लिए थोड़ा धीमा है।
जियोकोडिंग SQL उदाहरण # 2 (पंक्ति द्वारा पंक्ति) ~ औसत समय 1.2 / सेकंड है
जब मैं एक बार में इस तरह दिखने वाले एक स्टेटमेंट के साथ जियोकोड्स करके अपने पते में खुदाई करता हूं (btw, नीचे दिया गया उदाहरण 4.14 सेकंड लिया गया),
SELECT g.rating, ST_X(g.geomout) As lon, ST_Y(g.geomout) As lat,
(addy).address As stno, (addy).streetname As street,
(addy).streettypeabbrev As styp, (addy).location As city,
(addy).stateabbrev As st,(addy).zip
FROM geocode('6433 DROMOLAND Cir NW, MASSILLON, OH 44646',1) As g;
यह थोड़ा धीमा (2.5x प्रति रिकॉर्ड) है, लेकिन मैं क्वेरी समय के वितरण को देख सकता हूं और यह देख सकता हूं कि यह लंबे प्रश्नों का एक अल्पसंख्यक है जो इसे सबसे अधिक धीमा कर रहे हैं (केवल 5 मिलियन के पहले 2600 में लुकअप समय है)। यही है, शीर्ष 10% औसतन 100 ms, निचले 10% औसत 3.69 सेकंड ले रहे हैं, जबकि औसत 754 ms और माध्य 340 ms है।
# Just some interaction with the data in R
> range(lookupTimes[1:2600])
[1] 0.00 11.54
> median(lookupTimes[1:2600])
[1] 0.34
> mean(lookupTimes[1:2600])
[1] 0.7541808
> mean(sort(lookupTimes[1:2600])[1:260])
[1] 0.09984615
> mean(sort(lookupTimes[1:2600],decreasing=TRUE)[1:260])
[1] 3.691269
> hist(lookupTimes[1:2600]
अन्य विचार
अगर मुझे प्रदर्शन में वृद्धि का क्रम नहीं मिल सकता है, तो मुझे लगा कि मैं कम से कम धीमी जियोकोड बार की भविष्यवाणी करने के बारे में एक शिक्षित अनुमान लगा सकता हूं लेकिन यह मेरे लिए स्पष्ट नहीं है कि क्यों धीमे पते इतने अधिक समय लग रहे हैं। मैं एक सामान्य सामान्यीकरण चरण के माध्यम से मूल पता चला रहा हूं ताकि यह सुनिश्चित हो सके कि geocode()
फ़ंक्शन इसे प्राप्त करने से पहले इसे अच्छी तरह से स्वरूपित किया गया है:
sql=paste0("select pprint_addy(normalize_address('",myAddress,"'))")
गैर-पोस्टग्रैसेक डेटाबेस से उपयोगकर्ता पता तालिका में संकलित स्ट्रिंग कहां myAddress
है [Address], [City], [ST] [Zip]
।
मैंने pagc_normalize_address
एक्सटेंशन स्थापित करने की कोशिश की (विफल), लेकिन यह स्पष्ट नहीं है कि इससे मुझे जिस तरह का सुधार मिल रहा है, वह मिल जाएगा।
सुझाव के अनुसार निगरानी जानकारी जोड़ने का संपादन किया
प्रदर्शन
एक सीपीयू आंकी जाती है: [संपादित करें, प्रति क्वेरी केवल एक प्रोसेसर, इसलिए मेरे पास 5 अप्रयुक्त सीपीयू हैं]
top - 14:10:26 up 1 day, 3:11, 4 users, load average: 1.02, 1.01, 0.93
Tasks: 219 total, 2 running, 217 sleeping, 0 stopped, 0 zombie
Cpu(s): 15.4%us, 1.5%sy, 0.0%ni, 83.1%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 65056588k total, 64613476k used, 443112k free, 97096k buffers
Swap: 262139900k total, 77164k used, 262062736k free, 62745284k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3130 postgres 20 0 16.3g 8.8g 8.7g R 99.7 14.2 170:14.06 postmaster
11139 aolsson 20 0 15140 1316 932 R 0.3 0.0 0:07.78 top
11675 aolsson 20 0 135m 1836 1504 S 0.3 0.0 0:00.01 wget
1 root 20 0 19364 1064 884 S 0.0 0.0 0:01.84 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.06 kthreadd
डेटा विभाजन पर डिस्क गतिविधि का नमूना, जबकि एक खरीद 100% आंकी जाती है: [संपादित करें: इस क्वेरी द्वारा उपयोग में केवल एक प्रोसेसर]
# dstat -tdD dm-3 1
----system---- --dsk/dm-3-
date/time | read writ
12-06 14:06:36|1818k 3632k
12-06 14:06:37| 0 0
12-06 14:06:38| 0 0
12-06 14:06:39| 0 0
12-06 14:06:40| 0 40k
12-06 14:06:41| 0 0
12-06 14:06:42| 0 0
12-06 14:06:43| 0 8192B
12-06 14:06:44| 0 8192B
12-06 14:06:45| 120k 60k
12-06 14:06:46| 0 0
12-06 14:06:47| 0 0
12-06 14:06:48| 0 0
12-06 14:06:49| 0 0
12-06 14:06:50| 0 28k
12-06 14:06:51| 0 96k
12-06 14:06:52| 0 0
12-06 14:06:53| 0 0
12-06 14:06:54| 0 0 ^C
उस एसक्यूएल का विश्लेषण करें
यह EXPLAIN ANALYZE
उस क्वेरी से है:
"Update on addresses_to_geocode (cost=1.30..8390.04 rows=1000 width=272) (actual time=363608.219..363608.219 rows=0 loops=1)"
" -> Merge Left Join (cost=1.30..8390.04 rows=1000 width=272) (actual time=110.934..324648.385 rows=1000 loops=1)"
" Merge Cond: (a.patientid = g.patientid)"
" -> Nested Loop (cost=0.86..8336.82 rows=1000 width=184) (actual time=10.676..34.241 rows=1000 loops=1)"
" -> Subquery Scan on a (cost=0.43..54.32 rows=1000 width=32) (actual time=10.664..18.779 rows=1000 loops=1)"
" -> Limit (cost=0.43..44.32 rows=1000 width=4) (actual time=10.658..17.478 rows=1000 loops=1)"
" -> Index Scan using "addresses_to_geocode_PatientId_idx" on addresses_to_geocode addresses_to_geocode_1 (cost=0.43..195279.22 rows=4449758 width=4) (actual time=10.657..17.021 rows=1000 loops=1)"
" Filter: (rating IS NULL)"
" Rows Removed by Filter: 24110"
" -> Index Scan using "addresses_to_geocode_PatientId_idx" on addresses_to_geocode (cost=0.43..8.27 rows=1 width=152) (actual time=0.010..0.013 rows=1 loops=1000)"
" Index Cond: ("PatientId" = a.patientid)"
" -> Materialize (cost=0.43..18.22 rows=1000 width=96) (actual time=100.233..324594.558 rows=943 loops=1)"
" -> Subquery Scan on g (cost=0.43..15.72 rows=1000 width=96) (actual time=100.230..324593.435 rows=943 loops=1)"
" -> Limit (cost=0.43..5.72 rows=1000 width=42) (actual time=100.225..324591.603 rows=943 loops=1)"
" -> Index Scan using "addresses_to_geocode_PatientId_idx" on addresses_to_geocode ag (cost=0.43..23534259.93 rows=4449758000 width=42) (actual time=100.225..324591.146 rows=943 loops=1)"
" Filter: (rating IS NULL)"
" Rows Removed by Filter: 24110"
"Total runtime: 363608.316 ms"
Http://explain.depesz.com/s/vogS पर बेहतर ब्रेकडाउन देखें