तेजी से परीक्षण के लिए PostgreSQL का अनुकूलन करें


203

मैं एक सामान्य रेल एप्लिकेशन के लिए SQLite से PostgreSQL पर स्विच कर रहा हूं।

समस्या यह है कि पीजी के साथ रनिंग चश्मा धीमा हो गया।
SQLite पर यह ~ 34 सेकंड लिया, PG पर ~ 76 सेकंड है जो 2x धीमी से अधिक है

इसलिए अब मैं बिना किसी कोड संशोधनों के साथ SQLite के साथ युक्ति के प्रदर्शन को लाने के लिए कुछ तकनीकों को लागू करना चाहता हूं (आदर्श रूप से कनेक्शन कनेक्शन सेट करके, जो संभव नहीं है)।

मेरे सिर के ऊपर से कुछ स्पष्ट चीजें हैं:

  • RAM डिस्क (OSX पर RSpec के साथ अच्छा सेटअप देखने में अच्छा होगा)
  • अनलॉक्ड टेबल (क्या इसे पूरे डेटाबेस पर लागू किया जा सकता है, इसलिए मेरे पास सभी स्क्रिप्ट नहीं हैं?)

जैसा कि आप समझ गए होंगे कि मुझे विश्वसनीयता और बाकी की परवाह नहीं है (डीबी यहां सिर्फ एक फेंकने योग्य चीज है)।
मुझे पीजी से सबसे बाहर निकलने और इसे जितनी जल्दी हो सके बनाने की जरूरत है

सर्वश्रेष्ठ उत्तर आदर्श रूप का वर्णन होगा चाल बस कर रही है कि, के लिए सेटअप और उन चाल की खामियों।

अद्यतन: fsync = off + full_page_writes = offकेवल 65 सेकंड (~ -16 सेकंड) के लिए कम समय। अच्छी शुरुआत, लेकिन 34 के लक्ष्य से काफी दूर।

अद्यतन 2: मैंने रैम डिस्क का उपयोग करने की कोशिश की, लेकिन प्रदर्शन लाभ एक त्रुटि मार्जिन के भीतर था। तो इसके लायक प्रतीत नहीं होता है।

अद्यतन 3: * मुझे सबसे बड़ी अड़चन मिली और अब मेरे चश्मे SQLite वाले के रूप में तेजी से चलते हैं।

मुद्दा डेटाबेस क्लीनअप था जिसने ट्रंकेशन किया था । जाहिरा तौर पर SQLite वहाँ बहुत तेजी से रास्ता है।

इसे "ठीक" करने के लिए मैं प्रत्येक परीक्षण से पहले एक लेन-देन खोलता हूं और इसे अंत में वापस रोल करता हूं ।

~ 700 परीक्षणों के लिए कुछ संख्याएँ।

  • ट्रंकेशन: SQLite - 34s, PG - 76s।
  • लेन-देन: SQLite - 17s, PG - 18s।

SQLite के लिए 2x गति वृद्धि। पीजी के लिए 4 गुना स्पीड बढ़ाई।


2
मुझे वास्तव में संदेह है कि आप इसे SQLite के रूप में तेजी से जाने के लिए प्राप्त करेंगे। एक एकल उपयोगकर्ता के साथ SQLite insanely तेज है। SQLite का डिज़ाइन बहुत कम उपयोगकर्ता की संख्या और खराब माप के साथ बहुत तेज़ है; Pg की डिज़ाइन अच्छी है, लेकिन केवल एक उपयोगकर्ता के साथ सरल बल्क कार्य के लिए उतना तेज़ नहीं है।
क्रेग रिंगर

1
मुझे लगता है कि, लेकिन एक विशेष मामला है कि मुझे उम्मीद है कि पीजी (टेस्ट रन) के लिए ऑप्टिमाइज़ किया जा सकता है, इसलिए यह उतना ही तेज़ है जितना संभवतः हो सकता है। मैं इसे थोड़ा धीमा होने के लिए बुरा नहीं मानता, लेकिन 2.2x थोड़ा धीमा है। देखो मेरा मतलब है?
दिमित्री नागिरिंक

+1 यदि आपके पास इससे संबंधित कोई परिणाम मिला है तो मैं रैम डिस्क दृष्टिकोण के अपडेट में बहुत दिलचस्पी लूंगा।
tscho

@tscho मैं निश्चित रूप से इसे यहाँ पोस्ट करूँगा। लेकिन कुछ समय चाहिए क्योंकि मैं अन्य सामान पर काम कर रहा हूं और "पृष्ठभूमि में" पीजी सामान पर "शोध" कर रहा हूं।
दिमित्री नागिरनिंक

है डालने डेटा आपकी समस्या या क्वेरी करने ? यह आपके प्रश्न से स्पष्ट नहीं है।
a_horse_with_no_name

जवाबों:


281

सबसे पहले, हमेशा PostgreSQL के नवीनतम संस्करण का उपयोग करें। प्रदर्शन में सुधार हमेशा आ रहा है, इसलिए यदि आप एक पुराने संस्करण को ट्यून कर रहे हैं तो शायद आप अपना समय बर्बाद कर रहे हैं। उदाहरण के लिए, PostgreSQL 9.2 काफी तेजी से सुधार करता हैTRUNCATE और निश्चित रूप से सूचकांक-केवल स्कैन जोड़ता है। यहां तक ​​कि मामूली रिलीज का भी हमेशा पालन किया जाना चाहिए; देखेंसंस्करण नीति

क्या न करें

करो नहीं रैमडिस्क या अन्य गैर-टिकाऊ भंडारण पर एक टेबल-स्पेस डाल

यदि आप एक टेबलस्पेस खो देते हैं तो पूरा डेटाबेस क्षतिग्रस्त हो सकता है और महत्वपूर्ण काम के बिना उपयोग करना मुश्किल हो सकता है। इसका उपयोग करने की तुलना में बहुत कम लाभ हैUNLOGGED टेबल करने और वैसे भी कैश के लिए बहुत सारे रैम होने ।

यदि आप वास्तव में एक रैमडिस्क आधारित प्रणाली चाहते हैं, तो रैमडिस्क पर initdbएक नया क्लस्टरinitdb , तो रैमडिस्क पर एक नया पोस्टग्रेक्यूएल इंस्टेंस उदाहरण के , इसलिए आपके पास पूरी तरह से डिस्पोजेबल पोस्टग्रेक्यूएल उदाहरण है।

PostgreSQL सर्वर कॉन्फ़िगरेशन

परीक्षण करते समय, आप अपने सर्वर को गैर-टिकाऊ लेकिन तेजी से संचालन के लिए कॉन्फ़िगर कर सकते हैं ।

यह fsync=offPostgreSQL में सेटिंग के लिए एकमात्र स्वीकार्य उपयोगों में से एक है । यह सेटिंग बहुत हद तक बताती है कि PostgreSQL को ऑर्डर किए गए राइट्स या उस किसी भी अन्य डेटा-अखंडता-सुरक्षा और क्रैश-सुरक्षा सामान के साथ परेशान नहीं करना है, यदि आप पावर खो देते हैं या ओएस क्रैश होता है, तो यह आपके डेटा को पूरी तरह से कचरा करने की अनुमति देता है।

यह कहने की आवश्यकता नहीं है कि, आपको कभी भी fsync=offउत्पादन में सक्षम नहीं करना चाहिए जब तक कि आप Pg का उपयोग डेटा के लिए अस्थायी डेटाबेस के रूप में नहीं कर रहे हैं जब तक आप कहीं और से फिर से उत्पन्न नहीं कर सकते। यदि और केवल यदि आप fsync बंद करने के लिए कर रहे हैं full_page_writes, तो यह भी बंद हो सकता है, क्योंकि यह अब कोई अच्छा नहीं करता है। खबरदार है कि fsync=offऔर full_page_writesपर लागू क्लस्टर , स्तर तो वे प्रभावित करते हैं सब अपने PostgreSQL उदाहरण में डेटाबेस।

उत्पादन उपयोग के लिए आप संभवतः उपयोग कर सकते हैं synchronous_commit=offऔर ए सेट कर सकते हैं commit_delay, क्योंकि आपको fsync=offविशाल डेटा भ्रष्टाचार जोखिम के बिना समान लाभ प्राप्त होंगे । यदि आपके पास async कमिट सक्षम है, तो आपके पास हाल के डेटा के नुकसान की एक छोटी खिड़की है - लेकिन यह बात है।

यदि आपके पास DDL को थोड़ा बदलने का विकल्प है, तो आप UNLOGGEDवाल लॉगिंग से पूरी तरह से बचने के लिए Pg 9.1+ में तालिकाओं का भी उपयोग कर सकते हैं और सर्वर के क्रैश होने पर मिटाई जाने वाली तालिकाओं की कीमत पर वास्तविक गति को बढ़ा सकते हैं। सभी तालिकाओं को अनलोड करने के लिए कोई कॉन्फ़िगरेशन विकल्प नहीं है, इसे दौरान सेट किया जाना चाहिए CREATE TABLE। परीक्षण के लिए अच्छा होने के अलावा, यह आसान है अगर आपके पास डेटाबेस में उत्पन्न या महत्वहीन डेटा से भरा तालिकाओं हैं, अन्यथा सामान जिसमें आपको सुरक्षित होना चाहिए।

अपने लॉग की जाँच करें और देखें कि क्या आपको बहुत अधिक चौकियों के बारे में चेतावनी मिल रही है। यदि आप हैं, तो आपको अपने चेकपॉइंट्स को बढ़ाना चाहिए । आप अपने चेकपॉइंट_completion_target को सुचारू रूप से लिखने के लिए ट्यून करना चाहते हैं।

shared_buffersअपने वर्कलोड को फिट करने के लिए ट्यून करें। यह ओएस-निर्भर है, इस बात पर निर्भर करता है कि आपकी मशीन के साथ और क्या हो रहा है, और इसके लिए कुछ परीक्षण और त्रुटि की आवश्यकता होती है। चूक बेहद रूढ़िवादी हैं। यदि आप shared_buffersPostgreSQL 9.2 और उससे नीचे पर बढ़ते हैं, तो आपको OS की अधिकतम साझा मेमोरी सीमा बढ़ाने की आवश्यकता हो सकती है ; 9.3 और इसके बाद के संस्करण ने इससे बचने के लिए साझा मेमोरी का उपयोग कैसे किया।

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

जैसा कि एक अन्य पोस्टर ने कहा है कि यदि संभव हो तो अलग-अलग एचडीडी पर xlog और मुख्य तालिकाओं / अनुक्रमित को रखना बुद्धिमानी है। अलग विभाजन बहुत व्यर्थ है, आप वास्तव में अलग ड्राइव चाहते हैं। fsync=offयदि आप UNLOGGEDतालिकाओं का उपयोग कर रहे हैं, तो इस पृथक्करण का बहुत कम लाभ है, यदि आप साथ चल रहे हैं और लगभग कोई नहीं ।

अंत में, अपने प्रश्नों को ट्यून करें। सुनिश्चित करें कि आपके random_page_costऔर seq_page_costआपके सिस्टम के प्रदर्शन को प्रतिबिंबित करें, सुनिश्चित करें कि आपका effective_cache_sizeसही है, आदि EXPLAIN (BUFFERS, ANALYZE)व्यक्तिगत क्वेरी योजनाओं की जांच करने के लिए उपयोग करें , और auto_explainसभी धीमी क्वेरी की रिपोर्ट करने के लिए मॉड्यूल को चालू करें । आप अक्सर एक उचित सूचकांक बनाकर या लागत मापदंडों को बदलकर नाटकीय रूप से क्वेरी प्रदर्शन में सुधार कर सकते हैं।

AFAIK के रूप में पूरे डेटाबेस या क्लस्टर को सेट करने का कोई तरीका नहीं है UNLOGGED। ऐसा करने में सक्षम होना दिलचस्प होगा। PostgreSQL मेलिंग सूची पर पूछने पर विचार करें।

होस्ट ओएस ट्यूनिंग

कुछ ट्यूनिंग हैं जो आप ऑपरेटिंग सिस्टम स्तर पर भी कर सकते हैं। मुख्य बात यह है कि आप करना चाहते हैं ऑपरेटिंग सिस्टम को समझाने के लिए आक्रामक रूप से डिस्क को नहीं फ्लश करने के लिए है, क्योंकि आप वास्तव में परवाह नहीं करते हैं / जब वे इसे डिस्क पर बनाते हैं।

लिनक्स में आप वर्चुअल मेमोरी सबसिस्टम की dirty_*सेटिंग के साथ इसे नियंत्रित कर सकते हैं, जैसे dirty_writeback_centisecs

ट्यूनिंग राइटबैक सेटिंग्स के साथ बहुत ही सुस्त होने का एकमात्र मुद्दा यह है कि किसी अन्य प्रोग्राम द्वारा फ्लश करने से सभी पोस्टग्रेक्यूएल के संचित बफ़र्स को भी फ्लश किया जा सकता है, जिससे बड़े स्टॉल होते हैं जबकि सब कुछ लिखता है। आप किसी भिन्न फ़ाइल सिस्टम पर PostgreSQL चलाकर इसे कम करने में सक्षम हो सकते हैं, लेकिन कुछ फ़्लश डिवाइस-स्तर या पूरे-होस्ट-स्तर नहीं फ़ाइल-स्तर हो सकते हैं, इसलिए आप उस पर भरोसा नहीं कर सकते।

इस ट्यूनिंग को वास्तव में सेटिंग्स के साथ खेलने की आवश्यकता है, यह देखने के लिए कि आपके वर्कलोड के लिए सबसे अच्छा काम क्या है।

नए कर्नेल पर, आप यह सुनिश्चित करना चाहते हैं कि vm.zone_reclaim_modeयह शून्य पर सेट हो, क्योंकि यह NUMA सिस्टम (इन दिनों अधिकांश सिस्टम) के साथ गंभीर प्रदर्शन समस्याओं का कारण बन सकता है कि कैसे PostgreSQL प्रबंधन करता है shared_buffers

क्वेरी और वर्कलोड ट्यूनिंग

ये ऐसी चीजें हैं जिनके लिए कोड परिवर्तन की आवश्यकता होती है; वे आपके अनुरूप नहीं हो सकते। कुछ चीजें हैं जिन्हें आप लागू करने में सक्षम हो सकते हैं।

यदि आप बड़े लेनदेन में काम नहीं कर रहे हैं, तो शुरू करें। छोटे लेन-देन बहुत महंगे हैं, इसलिए आपको जब भी संभव हो तो सामान को बैचना चाहिए और ऐसा करने के लिए व्यावहारिक होना चाहिए। यदि आप async प्रतिबद्ध का उपयोग कर रहे हैं तो यह कम महत्वपूर्ण है, लेकिन फिर भी अत्यधिक अनुशंसित है।

जब भी संभव हो अस्थायी तालिकाओं का उपयोग करें। वे वाल ट्रैफ़िक उत्पन्न नहीं करते हैं, इसलिए वे आवेषण और अपडेट के लिए बहुत तेज़ हैं। कभी-कभी यह एक अस्थायी तालिका में डेटा के एक गुच्छा को घिसने के लायक है, हालांकि इसमें आपको हेरफेर करना पड़ता है, फिर INSERT INTO ... SELECT ...अंतिम तालिका में इसे कॉपी करने के लिए। ध्यान दें कि अस्थायी टेबल प्रति सत्र हैं; यदि आपका सत्र समाप्त होता है या आप अपना कनेक्शन खो देते हैं तो अस्थायी तालिका चली जाती है, और कोई अन्य कनेक्शन सत्र के अस्थायी तालिका की सामग्री नहीं देख सकता है।

यदि आप PostgreSQL 9.1 या नए का उपयोग कर रहे हैं, तो आप उन UNLOGGEDसत्रों के लिए तालिकाओं का उपयोग कर सकते हैं, जिन्हें आप खो सकते हैं, जैसे सत्र राज्य। ये विभिन्न सत्रों में दिखाई देते हैं और कनेक्शन के बीच संरक्षित होते हैं। यदि सर्वर अस्पष्ट रूप से बंद हो जाता है, तो वे छंटनी कर देते हैं, इसलिए उनका उपयोग किसी ऐसी चीज के लिए नहीं किया जा सकता है जिसे आप फिर से नहीं बना सकते हैं, लेकिन वे कैश, भौतिक विचारों, राज्य तालिकाओं आदि के लिए महान हैं।

सामान्य तौर पर, नहीं DELETE FROM blah;TRUNCATE TABLE blah;इसके बजाय का उपयोग करें ; जब आप किसी तालिका में सभी पंक्तियों को डंप कर रहे हों तो यह बहुत तेज़ होता है। TRUNCATEयदि आप कर सकते हैं तो एक कॉल में कई तालिकाओं को काटें । यदि आप TRUNCATESबार-बार छोटी-छोटी तालिकाओं के बहुत से कर रहे हैं, तो एक चेतावनी है ; देखें: Postgresql ट्रंकेशन गति

यदि आपके पास विदेशी कुंजियों पर अनुक्रमणिका नहीं है, तो DELETEउन विदेशी कुंजियों द्वारा संदर्भित प्राथमिक कुंजियों को शामिल करना बहुत धीमी गति से होगा। यदि आप कभी भी DELETEसंदर्भित तालिका से उम्मीद करते हैं तो ऐसे सूचकांक बनाना सुनिश्चित करें । इंडेक्स की आवश्यकता नहीं है TRUNCATE

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

हार्डवेयर

पूरे डेटाबेस को रखने के लिए पर्याप्त रैम होना एक बहुत बड़ी जीत है अगर आप इसे प्रबंधित कर सकते हैं।

यदि आपके पास पर्याप्त रैम नहीं है, तो तेज़ संग्रहण आपको बेहतर मिल सकता है। यहां तक ​​कि एक सस्ता एसएसडी कताई जंग पर एक बड़ा अंतर बनाता है। हालांकि उत्पादन के लिए सस्ते एसएसडी पर भरोसा न करें, वे अक्सर दुर्घटनाग्रस्त नहीं होते हैं और आपके डेटा को खा सकते हैं।

सीख रहा हूँ

ग्रेग स्मिथ की पुस्तक, PostgreSQL 9.0 उच्च प्रदर्शन कुछ पुराने संस्करण के संदर्भ के बावजूद प्रासंगिक है। यह एक उपयोगी संदर्भ होना चाहिए।

PostgreSQL सामान्य मेलिंग सूची में शामिल हों और उसका पालन करें।

पढ़ना:


10
मैं @GregSmith द्वारा PostgreSQL 9.0 उच्च प्रदर्शन की भी सिफारिश कर सकता हूं, यह वास्तव में एक महान पढ़ा है। पुस्तक डिस्क लेआउट से क्वेरी ट्यूनिंग के प्रदर्शन के हर पहलू को कवर करती है और आपको पीजी इंटर्नल्स की बहुत अच्छी समझ देती है।
tscho

10
मैंने PostgreSQL 9.1 के लिए पुस्तक के लिए एक अद्यतन जारी नहीं किया, इसके प्रकाशन के बाद से एकमात्र रिलीज़, क्योंकि 9.1 में पर्याप्त प्रदर्शन संबंधी परिवर्तन नहीं थे, इसे वारंट करने के लिए।
ग्रेग स्मिथ

3
महान लेखन। एक छोटे से अद्यतन के रूप में, "यदि आप साझा की जाने वाली_buffers को बढ़ाते हैं तो आपको OS की अधिकतम साझा मेमोरी सीमा बढ़ाने की आवश्यकता हो सकती है" PostgreSQL 9.3 के तहत अब (ज्यादातर उपयोगकर्ताओं के लिए) सही नहीं है: postgresql.org/docs/9.3/static/release-9-9 3.html # AEN114343
गननलौगर ब्रीम

1
@brauliobo मेरे परीक्षण अक्सर उच्च टीपीएस पर कई टीएक्स करते हैं ... क्योंकि मैं उत्पादन को अनुकरण करने की कोशिश करता हूं, जिसमें संगामिति-भारी कार्यभार शामिल हैं। यदि आपका मतलब "एकल-कनेक्शन, रैखिक परीक्षण" है, तो मैं आपसे सहमत हूं।
क्रेग रिंगर

1
stackoverflow.com/questions/11419536/… DELETE कुछ पंक्तियों वाली तालिकाओं के लिए TRUNCATE से अधिक तेज़ हो सकती है, जो परीक्षणों में मामला होने की संभावना है।
जोनाथन क्रॉसर

9

विभिन्न डिस्क लेआउट का उपयोग करें:

  • $ PGDATA के लिए अलग डिस्क
  • $ PGDATA / pg_xlog के लिए अलग डिस्क
  • मंदिर फ़ाइलों के लिए अलग-अलग डिस्क (प्रति डेटाबेस $ PGDATA / आधार // pgsql_tmp) (वर्क_म के बारे में ध्यान दें देखें)

postgresql.conf tweaks:

  • share_memory: उपलब्ध RAM का 30% लेकिन 6 से 8GB से अधिक नहीं। गहन वर्कलोड लिखने के लिए कम साझा मेमोरी (2GB - 4GB) का होना बेहतर प्रतीत होता है
  • work_mem: अधिकतर सॉर्ट / एकत्रीकरण के साथ चुनिंदा प्रश्नों के लिए। यह प्रति कनेक्शन सेटिंग है और क्वेरी कई बार उस मान को आवंटित कर सकती है। यदि डेटा फिट नहीं हो सकता है तो डिस्क का उपयोग किया जाता है (pgsql_tmp)। आपको कितनी मेमोरी की आवश्यकता है, यह देखने के लिए "एक्सप्लेन एनालिसिस" चेक करें
  • fsync और synchronous_commit: डिफ़ॉल्ट मान सुरक्षित हैं लेकिन यदि आप खोए हुए डेटा को सहन कर सकते हैं तो आप बंद कर सकते हैं
  • random_page_cost: यदि आपके पास SSD या तेज RAID सरणी है, तो आप इसे 2.0 (RAID) या इससे भी कम (1.1) SSD तक कम कर सकते हैं
  • चेकपॉइंट_सेक्शन: आप उच्च 32 या 64 पर जा सकते हैं और चेकपॉइंट_completion_target को 0.9 में बदल सकते हैं। लोअर वैल्यू क्रैश रिकवरी के बाद तेजी से अनुमति देता है

4
ध्यान दें कि यदि आप पहले से साथ चल रहे हैं fsync=off, तो pg_xlog को एक अलग डिस्क पर रखने से बहुत सुधार नहीं होता है।
intgr

SSD के लिए 1.1 का मान बहुत ही अयोग्य है। मैं स्वीकार करता हूं कि यह वही है जो कुछ पेशेवरों ने नेत्रहीन रूप से सिफारिश की है। यहां तक ​​कि SSDs यादृच्छिक रीड की तुलना में अनुक्रमिक रीडर्स के लिए काफी तेज हैं।
एक्यूमेनस

@ABB हां, लेकिन आपको काम पर ओएस बफर कैशिंग प्रभाव भी मिला है। उन सभी परों को वैसे भी थोड़ा-सा हाथ-लहरदार ...
क्रेग रिंगर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.