2012-10-17 7 views
8

मेरे पास 10 मीटर पंक्तियों वाला एक बड़ा टेबल है। और मुझे प्रत्येक पंक्ति के लिए कुछ सांख्यिकीय मूल्य प्राप्त करने की आवश्यकता है। मेरे पास ऐसा फ़ंक्शन है जो इस मान को उत्पन्न करता है, उदाहरण के लिए GetStatistic(uuid)। यह काम करता है बहुत धीमी गति से काम करता है और परिणाम मूल्य बार नहीं बदलता है, इसलिए मैं अपने कॉलम खोजें Statistic बना लिया है, और एक दिन में एक बार इस तरह क्वेरी निष्पादित करें:पोस्टग्रेस्क्ल। Paralell में अद्यतन क्वेरी चला सकते हैं?

UPDATE MyTable SET Statistic = GetStatistic(ID); 

और चुनिंदा प्रश्नों में मैं GetStatistic बुला बिना स्तंभ Statistic का उपयोग कार्य करता है।

समस्या यह है कि मेरे उत्पादन सर्वर में 64 सीपीयू और बहुत सारी मेमोरी है, इसलिए लगभग सभी डीबी को रैम में कैश किया जा सकता है, लेकिन यह क्वेरी केवल एक सीपीयू का उपयोग करती है और निष्पादित करने के लिए 2 या 3 घंटे की आवश्यकता होती है।

GetStatistic फ़ंक्शन उपयोग तालिका, जो अद्यतन क्वेरी के सभी निष्पादन के दौरान निरंतर हैं। क्या मैं सभी उपलब्ध सीपीयू का उपयोग करके अलग-अलग पंक्तियों के लिए पैराल में गेटस्टैटिस्टिक की गणना करने के लिए पोस्टग्रे प्राप्त करने के लिए क्वेरी संशोधित कर सकता हूं?

+0

फ़ंक्शन का उपयोग क्यों करें, क्या ऐसा कुछ भी है जो सादे एसक्यूएल द्वारा पूरा नहीं किया जा सकता है? क्या फ़ंक्शन को केवल वर्तमान पंक्ति से मानों की आवश्यकता होती है, या इसमें डेटा के अन्य स्रोत भी शामिल हैं (: = टेबल)? बीटीडब्ल्यू: हमें समारोह दिखाएं। – wildplasser

+0

इस क्वेरी की योजना की जांच करें, आप देखेंगे कि इस फ़ंक्शन को 10 एम बार कहा जाता है। हो सकता है कि इसे शुद्ध एसक्यूएल में लिखना बेहतर होगा और यह बहुत तेज हो सकता है। –

उत्तर

9

PostgreSQL प्रत्येक क्वेरी को एक बैकएंड में निष्पादित करता है, जो एक थ्रेड के साथ एक प्रक्रिया है। यह एक क्वेरी के लिए एक से अधिक CPU का उपयोग नहीं कर सकता है। यह कुछ हद तक सीमित है जो I/O समेकन में एक क्वेरी के भीतर प्राप्त कर सकता है, वास्तव में केवल बिटमैप इंडेक्स स्कैन के लिए समवर्ती I/O कर रहा है और अन्यथा समवर्ती I/O के लिए ओएस और डिस्क सिस्टम पर निर्भर करता है।

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

आप क्या कर सकते हैं नौकरी को टुकड़ों में विभाजित करें और उन्हें श्रमिकों को सौंप दें। आप के साथ इस उल्लेख किया है:

मैं बदल सकते हैं क्वेरी सभी उपलब्ध CPU के उपयोग, postgre एक साथ अलग-अलग पंक्तियों के लिए समानांतर में GetStatistic गणना करने के लिए प्राप्त करने के लिए?

उपकरणों की एक किस्म, DBlink, PL/Proxy, pgbouncer और PgPool-II कि काम के इस प्रकार के साथ मदद करने के लिए तैयार कर रहे हैं की तरह कर रहे हैं। वैकल्पिक रूप से, आप इसे स्वयं ही कर सकते हैं, कहें (कहें) 8 कर्मचारी जो प्रत्येक डेटाबेस से कनेक्ट होते हैं और गैर-ओवरलैपिंग आईडी श्रेणियों वाले UPDATE ... WHERE id BETWEEN ? AND ? कथन करते हैं। एक अधिक परिष्कृत विकल्प है कि कतार नियंत्रक हाथों को श्रमिकों को 1000 आईडी कहने के लिए कहें जो UPDATE है, तब सीमा एक नया मांगती है।

ध्यान दें कि 64 सीपीयू का यह मतलब नहीं है कि 64 समवर्ती श्रमिक आदर्श हैं। लिखने की बात आने पर आपकी डिस्क I/O एक कारक भी है। और (यदि इस डेटा के लिए आपकी व्यावसायिक आवश्यकताओं के लिए सुरक्षित है) synchronous_commit = 'off' का उपयोग करने के लिए आप UPDATE लेन-देन सेट करते हैं तो आप अपने I/O की लागत को थोड़ा सा मदद कर सकते हैं, तो सिंक से लोड को काफी कम किया जाना चाहिए। फिर भी, यह संभावना है कि 64 समवर्ती श्रमिकों के नीचे सबसे अच्छा थ्रूपुट हासिल किया जाएगा।

यह अत्यधिक संभावना है कि आपके GetStatistic फ़ंक्शन को एक लूप-भारी प्रक्रियात्मक पीएल/पीजीएसक्यूएल फ़ंक्शन की वजह से एक इनलाइन एसक्यूएल फ़ंक्शन या दृश्य में परिवर्तित करके बहुत तेज बनाया जा सकता है। यदि आप इस समारोह को दिखाते हैं तो यह मदद कर सकता है।

संबंधित मुद्दे