Postgres 9.2 पर बढ़ते वर्क_म और शेयर्ड_बफर्स ​​प्रश्नों को काफी धीमा कर देते हैं


39

मेरे पास एक पोस्टग्रेएसक्यू 9.2 उदाहरण है जो आरएचईएल 6.3 पर चल रहा है, 16 जीबी रैम के साथ 8-कोर मशीन है। सर्वर इस डेटाबेस के लिए समर्पित है। यह देखते हुए कि डिफ़ॉल्ट postgresql.conf मेमोरी सेटिंग्स के संबंध में काफी रूढ़िवादी है, मैंने सोचा कि पोस्टग्रेज को अधिक मेमोरी का उपयोग करने की अनुमति देने के लिए यह एक अच्छा विचार हो सकता है। मेरे आश्चर्य के लिए, wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server पर निम्नलिखित सलाह व्यावहारिक रूप से मेरे द्वारा चलाए जाने वाले प्रत्येक प्रश्न को धीमा कर देती है, लेकिन यह अधिक जटिल प्रश्नों पर स्पष्ट रूप से ध्यान देने योग्य है।

मैंने भी pgtune चलाने की कोशिश की, जिसमें अधिक मापदंडों के साथ निम्नलिखित सिफारिश दी गई, लेकिन इससे कुछ भी नहीं बदला। यह सुझाव देता है कि 1/4 रैम आकार के शेयर्ड_बफर्स ​​जो कहीं और (और विशेष रूप से पीजी विकी पर) सलाह के अनुरूप लगता है।

default_statistics_target = 50
maintenance_work_mem = 960MB
constraint_exclusion = on
checkpoint_completion_target = 0.9
effective_cache_size = 11GB
work_mem = 96MB
wal_buffers = 8MB
checkpoint_segments = 16
shared_buffers = 3840MB
max_connections = 80

मैंने सेटिंग्स को बदलने (उपयोग करने reindex database) के बाद पूरे डेटाबेस को रीइन्डेक्सिंग करने की कोशिश की , लेकिन इससे भी मदद नहीं मिली। मैंने Share_buffers और work_mem के साथ खेला। धीरे-धीरे उन्हें बहुत रूढ़िवादी डिफ़ॉल्ट मूल्यों (128k / 1MB) से बदलना धीरे-धीरे प्रदर्शन में कमी आई।

मैं EXPLAIN (ANALYZE,BUFFERS)कुछ प्रश्नों पर भाग गया और अपराधी को लगता है कि हैश जॉइन काफी धीमा है। यह मेरे लिए स्पष्ट क्यों नहीं है।

कुछ विशिष्ट उदाहरण देने के लिए, मेरे पास निम्नलिखित प्रश्न हैं। यह डिफ़ॉल्ट कॉन्फ़िगरेशन पर ~ 2100ms में चलता है और ~ बफर विस्तार के साथ कॉन्फ़िगरेशन पर ~ 3300ms:

select count(*) from contest c
left outer join contestparticipant cp on c.id=cp.contestId
left outer join teammember tm on tm.contestparticipantid=cp.id
left outer join staffmember sm on cp.id=sm.contestparticipantid
left outer join person p on p.id=cp.personid
left outer join personinfo pi on pi.id=cp.personinfoid
where pi.lastname like '%b%' or pi.firstname like '%a%';

EXPLAIN (ANALYZE,BUFFERS) उपरोक्त क्वेरी के लिए:

सवाल यह है कि जब मैं बफर साइज़ बढ़ाता हूँ तो प्रदर्शन में कमी क्यों आ रही है? मशीन निश्चित रूप से स्मृति से बाहर नहीं चल रही है। यदि ओएस में साझा मेमोरी है ( shmmaxऔर shmall) बहुत बड़े मूल्यों पर सेट है, तो यह समस्या नहीं होनी चाहिए। मुझे पोस्टग्रेज लॉग में कोई त्रुटि नहीं मिल रही है। मैं डिफ़ॉल्ट कॉन्फ़िगरेशन में ऑटोवैक्यूम चला रहा हूं लेकिन मुझे उम्मीद नहीं है कि इसके साथ कुछ भी करना है। सभी प्रश्न एक ही मशीन पर कुछ सेकंड के लिए चलाए गए थे, बस परिवर्तित कॉन्फ़िगरेशन (और पुनः आरंभ किए गए पीजी) के साथ।

संपादित करें: मुझे सिर्फ एक विशेष रूप से दिलचस्प तथ्य मिला: जब मैं अपने मध्य 2010 के iMac (OSX 10.7.5) पर भी यही परीक्षण करता हूं, तो Postgres 9.2.1 और 16GB RAM के साथ, मुझे धीमा अनुभव नहीं होता है। विशेष रूप से:

set work_mem='1MB';
select ...; // running time is ~1800 ms
set work_mem='96MB';
select ...' // running time is ~1500 ms

जब मैं सर्वर पर ठीक उसी डेटा के साथ एक ही क्वेरी (ऊपर वाला) करता हूं तो मुझे 96 एमबी के साथ वर्क_म = 1 एमबी और 3200 एमएस के साथ 2100 एमएस मिलते हैं।

मैक में एसएसडी है इसलिए यह काफी तेजी से है, लेकिन यह एक व्यवहार प्रदर्शित करता है जिसकी मुझे उम्मीद है।

Pgsql- प्रदर्शन पर अनुवर्ती चर्चा भी देखें ।


1
ऐसा लगता है कि धीमे मामले में हर कदम में लगातार धीमा है। क्या अन्य सेटिंग्स समान थीं?
dezso

1
यह संभवतः आपके समय के लायक है क्योंकि यह सामान्य है कि यह है कि एक और अधिक विशिष्ट मंच पर यह पूछने के लिए। इस मामले में मैं pgsql- सामान्य मेलिंग सूची अभिलेखागार का
कॉलिन का हार्ट हार्ट

1
ओह, और वापस रिपोर्ट करें और यदि आपको उत्तर मिल जाए तो कृपया अपने स्वयं के प्रश्न का उत्तर दें! (यह अनुमति है, यहां तक ​​कि प्रोत्साहित किया गया है)।
कॉलिन 'टी हार्ट

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

2
प्रश्न अब
pgsql-

जवाबों:


28

सबसे पहले, यह ध्यान रखें कि work_mem प्रति ऑपरेशन है और इसलिए यह बहुत जल्दी प्राप्त कर सकता है। सामान्य तौर पर अगर आपको किसी प्रकार की परेशानी नहीं हो रही है तो धीमी गति से होने से मैं वर्क_म को अकेला छोड़ दूंगा जब तक आपको इसकी आवश्यकता न हो।

आपकी क्वेरी योजनाओं को देखते हुए, एक बात जो मुझे चौंकाती है, वह यह है कि बफर हिट दो योजनाओं को देखते हुए बहुत भिन्न होती है, और यह कि अनुक्रमिक स्कैन भी धीमा होता है। मुझे संदेह है कि इस मुद्दे को पढ़ने-आगे कैशिंग और उसके लिए कम जगह होने के साथ क्या करना है। इसका मतलब यह है कि आप अनुक्रमित के पुन: उपयोग और डिस्क पर पढ़ने की मेज के खिलाफ स्मृति को पूर्वाग्रह कर रहे हैं।


मेरी समझ यह है कि PostgreSQL डिस्क से पढ़ने से पहले एक पृष्ठ के लिए कैश को देखेगा क्योंकि यह वास्तव में नहीं जानता है कि क्या ओएस कैश में वह पेज होगा। क्योंकि पेज फिर कैश में रह रहे हैं और क्योंकि यह कैश ओएस कैश से धीमा है, इसलिए यह उन प्रश्नों के प्रकार को बदल देता है जो कि धीमी गति से बनाम के प्रकार हैं। वास्तव में कार्य योजनाओं को पढ़ने से, काम की समस्याओं से अलग, ऐसा लगता है कि आपकी सभी क्वेरी जानकारी कैश से आती है, लेकिन यह प्रश्न है कि कैश किसका है।

work_mem : सॉर्ट या संबंधित जॉइन ऑपरेशन के लिए हम कितनी मेमोरी आवंटित कर सकते हैं। यह प्रति ऑपरेशन है, प्रति कथन या प्रति-अंत में नहीं है, इसलिए एक एकल जटिल क्वेरी स्मृति की इस राशि का कई बार उपयोग कर सकती है। यह स्पष्ट नहीं है कि आप इस सीमा को मार रहे हैं, लेकिन यह ध्यान देने योग्य है और जागरूक है। यदि आप इसे बहुत अधिक बढ़ाते हैं, तो आप वह मेमोरी खो देते हैं जो रीड कैश और शेयर्ड बफ़र्स के लिए उपलब्ध हो सकती है।

share_buffers : वास्तविक PostgreSQL पृष्ठ कतार में आवंटित करने के लिए कितनी मेमोरी। अब, आदर्श रूप से आपके डेटाबेस का दिलचस्प सेट यहाँ रखी गई मेमोरी में और रीड बफ़र्स में रहेगा। हालांकि, यह क्या सुनिश्चित करता है कि सभी बैकएंड में सबसे अधिक बार उपयोग की जाने वाली जानकारी कैश हो जाती है और डिस्क में फ्लश नहीं होती है। लिनक्स पर यह कैश ओएस डिस्क कैश की तुलना में काफी धीमा है, लेकिन यह गारंटी देता है कि ओएस डिस्क कैश डॉस और एसक्यूएल के लिए पारदर्शी नहीं है। यह बहुत स्पष्ट रूप से है जहाँ आपकी समस्या है।

तो क्या होता है कि जब हमारे पास एक अनुरोध होता है, तो हम पहले साझा किए गए बफ़र्स की जांच करते हैं क्योंकि पोस्टग्रेज़क्यूएल को इस कैश का गहरा ज्ञान है, और पृष्ठों की तलाश करें। यदि वे वहां नहीं हैं तो हम ओएस को उन्हें फ़ाइल से खोलने के लिए कहते हैं, और यदि ओएस ने परिणाम को कैश किया है तो यह कैश की गई कॉपी लौटाता है (यह साझा बफ़र्स की तुलना में तेज़ है, लेकिन Pg यह नहीं बता सकता है कि यह कैश किया गया है या चालू है डिस्क, और डिस्क बहुत धीमी है इसलिए PostgreSQL आमतौर पर वह मौका नहीं लेगा)। ध्यान रखें कि यह यादृच्छिक बनाम अनुक्रमिक पेज एक्सेस को भी प्रभावित करता है। इसलिए आपको कम शेयर्ड_बफर्स ​​सेटिंग्स के साथ बेहतर प्रदर्शन मिल सकता है।

मेरी समझदारी यह है कि आप शायद बेहतर हों, या कम से कम अधिक सुसंगत, बड़े साझा_बफ़र सेटिंग्स के साथ उच्च संगामिति वातावरण में प्रदर्शन। यह भी ध्यान रखें कि PostgreSQL इस मेमोरी को पकड़ लेता है और इसे होल्ड करता है यदि आपके पास सिस्टम पर चलने वाली अन्य चीजें हैं, तो पढ़ने वाले बफ़र्स अन्य प्रक्रियाओं द्वारा पढ़ी गई फ़ाइलों को पकड़ लेंगे। यह एक बहुत बड़ा और जटिल विषय है। बड़ी साझा बफर सेटिंग्स प्रदर्शन की बेहतर गारंटी प्रदान करती हैं लेकिन कुछ मामलों में कम प्रदर्शन प्रदान कर सकती हैं।


10

बढ़ते विरोधाभासी प्रभाव के अलावा, जो work_memप्रदर्शन को बढ़ाता है ( @Chris में एक स्पष्टीकरण हो सकता है), आप कम से कम दो तरीकों से अपने कार्य में सुधार कर सकते हैं।

  • दो नकली LEFT JOINके साथ फिर से लिखें JOIN। यह क्वेरी प्लानर को भ्रमित कर सकता है और हीन योजनाओं को जन्म दे सकता है।

SELECT count(*) AS ct
FROM   contest            c
JOIN   contestparticipant cp ON cp.contestId = c.id
JOIN   personinfo         pi ON pi.id = cp.personinfoid
LEFT   JOIN teammember    tm ON tm.contestparticipantid = cp.id
LEFT   JOIN staffmember   sm ON sm.contestparticipantid = cp.id
LEFT   JOIN person        p  ON p.id = cp.personid
WHERE (pi.firstname LIKE '%a%'
OR     pi.lastname  LIKE '%b%')
  • यह मानते हुए कि आपके वास्तविक खोज पैटर्न अधिक चयनात्मक हैं, ट्रायग्राम इंडेक्सों का उपयोग करें pi.firstnameऔर pi.lastnameगैर-एंकर युक्त LIKEखोजों का समर्थन करें । (जैसे शॉर्ट पैटर्न '%a%'का समर्थन किया जाता है, लेकिन गैर-चयनात्मक विधेयकों के लिए मदद के लिए एक सूचकांक की संभावना नहीं है।)

CREATE INDEX personinfo_firstname_gin_idx ON personinfo USING gin (firstname gin_trgm_ops);
CREATE INDEX personinfo_lastname_gin_idx  ON personinfo USING gin (lastname gin_trgm_ops);

या एक बहुरंगी सूचकांक:

CREATE INDEX personinfo_name_gin_idx ON personinfo USING gin (firstname gin_trgm_ops, lastname gin_trgm_ops);

अपनी क्वेरी को काफी तेज करना चाहिए। इसके लिए आपको अतिरिक्त मॉड्यूल pg_trgm इंस्टॉल करना होगा। इन संबंधित प्रश्नों के विवरण:


इसके अलावा, क्या आपने work_mem स्थानीय रूप से सेटिंग की कोशिश की है - केवल वर्तमान लेनदेन के लिए ?

SET LOCAL work_mem = '96MB';

यह समवर्ती लेनदेन को अधिक रैम खाने से बचाता है, संभवतः एक दूसरे को भूखा रखता है।


3
मैं इरविन के स्थानीय कार्य_मम को दूसरा सुझाव देना चाहता हूं। क्योंकि work_mem प्रश्नों के प्रकार को बदल देता है जो तेज़ हैं, आपको कुछ प्रश्नों के लिए इसे बदलने की आवश्यकता हो सकती है। Ie कम work_mem स्तर उन प्रश्नों के लिए सबसे अच्छा है जो जटिल तरीकों से रिकॉर्ड की छोटी संख्याओं को जोड़ते / जोड़ते हैं (यानी बहुत सारे जोड़) जबकि उच्च work_mem स्तर उन प्रश्नों के लिए सर्वोत्तम होते हैं जिनमें कुछ प्रकार होते हैं लेकिन जो बड़ी संख्या में पंक्तियों को एक साथ क्रमबद्ध या जोड़ते हैं ।
क्रिस ट्रेवर्स

मैंने इस बीच क्वेरी में सुधार किया (प्रश्न पिछले साल अक्टूबर से है) लेकिन धन्यवाद :) यह प्रश्न विशेष क्वेरी की तुलना में अप्रत्याशित प्रभाव के बारे में अधिक है। क्वेरी मुख्य रूप से प्रभाव प्रदर्शित करने के लिए कार्य करती है। सूचकांक पर टिप के लिए धन्यवाद, मैं कोशिश करूँगा!
पेट्र प्रूस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.