2012-01-04 14 views
6

पर अपडेट चलाना SQL सर्वर 2005 में मेरे पास एक बड़ी तालिका (~ 170 मिलियन पंक्तियां, 2 nvarchar और 7 int कॉलम) है जो लगातार डाला जा रहा है। सब कुछ प्रदर्शन परिप्रेक्ष्य से इसके साथ ठीक काम करता है, लेकिन प्रत्येक बार एक बार मुझे तालिका में पंक्तियों का एक सेट अपडेट करना होता है जो समस्याओं का कारण बनता है। यह ठीक काम करता है अगर मैं डेटा का एक छोटा सा सेट अपडेट करता हूं, लेकिन अगर मुझे 40,000 रिकॉर्ड का एक सेट अपडेट करना है या तो टेबल पर लगभग 3 मिनट और ब्लॉक लगते हैं जो इन्सर्ट विफल होने लगने से समस्याएं पैदा करते हैं।बड़ी, भारी उपयोग की गई तालिका

यदि मैं अद्यतन किए जाने वाले डेटा को वापस पाने के लिए केवल एक चयन चलाता हूं तो मुझे लगभग 2 सेकंड में 40k रिकॉर्ड वापस मिलते हैं। यह केवल अद्यतन है जो हमेशा के लिए लेते हैं। यह अद्यतन के लिए निष्पादन योजना में प्रतिबिंबित होता है जहां क्लस्टर इंडेक्स अपडेट लागत का 9 0% और पंक्तियों को 10% लागत लेने के लिए इंडेक्स की तलाश और शीर्ष ऑपरेटर लेता है। जिस कॉलम को मैं अपडेट कर रहा हूं वह किसी भी इंडेक्स कुंजी का हिस्सा नहीं है, इसलिए ऐसा कुछ भी पुनर्गठित करने जैसा नहीं है।

क्या किसी के पास कोई विचार है कि इसे कैसे बढ़ाया जा सकता है? मेरा विचार अब एक ऐसी सेवा लिखना है जो यह देखने के लिए होगा कि इन अद्यतनों को कब करना होगा, उन रिकॉर्ड्स को वापस खींचें जिन्हें अपडेट किया जाना है, और फिर उन्हें एक-एक करके लूप करें और अपडेट करें। यह मेरी व्यावसायिक जरूरतों को पूरा करेगा, लेकिन यह बनाए रखने के लिए एक और मॉड्यूल है और अगर मैं इसे चीजों के डीबीए पक्ष से ठीक कर सकता हूं तो मुझे अच्छा लगेगा।

किसी भी विचार के लिए धन्यवाद!

+0

आप पोस्ट कर सकते हैं तालिका परिभाषा (प्राथमिक कुंजी, अनुक्रमित, आदि सहित), मेज पर किसी भी ट्रिगर और वास्तविक अद्यतन क्वेरी स्वयं? – MatBailie

+0

सिर्फ एक विचार: शेरिंग – Adrian

+0

@ एड्रियन - लेकिन यदि अपडेट किए गए फ़ील्ड क्लस्टर इंडेक्स में नहीं हैं (या स्पष्ट रूप से कोई अन्य इंडेक्स) निष्पादन योजना क्लस्टर्ड इंडेक्स अपडेट क्यों दिखाएगी? – MatBailie

उत्तर

0

मस्जिद ब्रूट-बल (और सबसे सरल) तरीका है जैसा आपने बताया है, मूल सेवा है। सर्वर और/या डेटा लोड पर लोड के साथ स्केल करने में सक्षम होने का इसका लाभ है।

उदाहरण के लिए, आप नई जानकारी से ऐसे होना चाहिए का एक सेट है, तो यथाशीघ्र, तो आप बैच का आकार बदल सकती है। इसके विपरीत, कम महत्वपूर्ण अपडेट के लिए, यदि आप प्रत्येक अद्यतन को डीबी पर कुछ दबाव से छुटकारा पाने के लिए "बहुत लंबा" ले रहा है तो अपडेट "सर्वर" धीमा हो सकता है।

इस तरह की "दिल की धड़कन" प्रक्रिया प्रणाली में आम है और बहुत सही परिस्थितियों में शक्तिशाली हो सकती है।

1

असल में यदि आप nvarchar कॉलम अपडेट करते हैं तो यह पृष्ठों को पुनर्गठित कर सकता है। इन कॉलमों के अपडेट के आधार पर वे अद्यतन से पहले आरक्षित स्थान से बड़ा होने का रिकॉर्ड कर सकते हैं। (विवरण अब nvarchar http://www.databasejournal.com/features/mssql/physical-database-design-consideration.html में संग्रहीत किया जाता है देखें।)

तो कहते हैं कि एक रिकार्ड 20 nvarchar में सहेजा वर्णों की स्ट्रिंग है - यह (सूचक के लिए 2) लेता है 20 * 2 + 2 अंतरिक्ष में बाइट्स। यह आपकी तालिका में प्रारंभिक डालने पर लिखा गया है (सूचकांक संरचना के आधार पर)। SQL सर्वर केवल उतना ही स्थान उपयोग करेगा जितना आपका nvarchar वास्तव में लेता है।

अब अद्यतन आता है और 40 वर्णों की एक स्ट्रिंग डालता है। और ओह, आपके सूचकांक की आपकी पत्ती संरचना के भीतर रिकॉर्ड के लिए जगह अचानक बहुत छोटी है। तो अद्यतन अद्यतन की वास्तविक जगह को इंगित करने वाली पुरानी जगह में एक पॉइंटर के साथ एक अलग भौतिक स्थान पर रिकॉर्ड चला जाता है।

यह तब आपकी अनुक्रमणिका को बाँधने का कारण बनता है और क्योंकि पूरे भौतिक संरचना को बदलने की आवश्यकता है, आप दृश्यों के पीछे बहुत सारे इंडेक्स काम चल रहे हैं। एक विशेष टेबल लॉक वृद्धि के कारण बहुत संभावना है।

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

+0

आप अपने पुनर्निर्माण से बचने के लिए अपडेट करने से पहले एक इंडेक्स को भी अक्षम कर सकते हैं। पेज-> टेबल लॉक - हमारे पास एएसएफएएस के पास यहां बड़ी संख्या में पेज लॉक की एक बड़ी संख्या है। 170 मीटर रिकॉर्ड शायद 40k रिकॉर्ड से अवरुद्ध किए जाएंगे, हालांकि यह 5k ताले होंगे! :))। इसके अलावा मैं इस बड़ी तालिका को पार्टिशन करने की भी सिफारिश करता हूं, यह अभी भी नहीं हुआ है। धन्यवाद साथी –

+0

अद्यतन nvarchar कॉलम को स्पर्श नहीं कर रहा है, केवल int कॉलम ताकि डेटा पुनर्गठन नहीं किया जाना चाहिए। @ सर्गी, मैंने विभाजन में देखा, लेकिन मुझे विभाजन को बनाए रखने का एक अच्छा तरीका नहीं देखा। यह शायद मेरी प्रदर्शन आवश्यकताओं को पूरा करेगा, लेकिन रखरखाव सामान के साथ आ जाएगा। – kylememe

0

यह वायर्ड है कि आपका विश्लेषक कह रहा है कि क्लस्टर इंडेक्स को अपडेट करने में समय लगता है। जब आप अपडेट करते हैं तो डेटा का आकार बदल जाता है? ऐसा लगता है कि वर्कर डेटा को पुनः व्यवस्थित करने के लिए चला रहा है जिसके लिए इंडेक्स पॉइंटर्स के अपडेट की आवश्यकता हो सकती है (केएमबी के रूप में पहले से ही बताया गया है)। उस स्थिति में आप डेटा और इंडेक्स पृष्ठों पर% मुक्त आकार को बढ़ाना चाहते हैं ताकि डेटा और इंडेक्स पेज रिलिकिंक/रीयलोकेशन के बिना बढ़ सकें। चूंकि अद्यतन एक आईओ गहन ऑपरेशन है (पढ़ने के विपरीत, जिसे buffered किया जा सकता है) प्रदर्शन भी कई कारकों पर निर्भर करता है

1) क्या आपकी तालिका डेटा द्वारा विभाजित है 2) क्या संपूर्ण तालिका एक ही SAN डिस्क में है (या है SAN अच्छी तरह से धारीदार है?) 3) लेनदेन लॉगिंग कैसे वर्बोज़ है। लेनदेन लॉगगन का बफर आकार बड़े पैमाने पर आवेषणों को बढ़ावा देने के लिए लॉग को बड़े लिखने के समर्थन में वृद्धि कर सकता है?

यह भी महत्वपूर्ण है कि आप कौन सी एपीआई/भाषा का उपयोग कर रहे हैं? उदाहरण के लिए जेडीबीसी एक बैच अपडेट फीचर का समर्थन करता है जो अपडेट्स को थोड़ा सा कुशल बनाता है यदि आप कई अपडेट कर रहे हैं।

1

आपको 40k पंक्तियों में से एक के बजाय कई अपडेट में अपने अपडेट को बैच करना चाहिए (एक समय में 10000 कहें, टेस्ट!)।

इस तरह आप एक टेबल लॉक से बचेंगे, एसक्यूएल सर्वर केवल टेबल लॉक पर चढ़ने से पहले 5000 ताले (पृष्ठ या पंक्ति) लेगा और यहां तक ​​कि यह बहुत अनुमानित नहीं है (मेमोरी प्रेशर इत्यादि)। इस फेशन में किए गए छोटे अपडेट कम से कम समेकित मुद्दों से बचेंगे जो आप अनुभव कर रहे हैं।

आप किसी सेवा या फ़ायरहोज कर्सर का उपयोग करके अपडेट बैच कर सकते हैं।

अधिक जानकारी के लिए इस पढ़ें: http://msdn.microsoft.com/en-us/library/ms184286.aspx

आशा इस मदद करता है

रॉबर्ट

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