2010-06-02 15 views
14

मान लीजिए कि आप और के बारे में 5 मिलियन रिकॉर्ड के साथ एक मेज एक nvarchar(max) स्तंभ बड़े पाठ डेटा के साथ करते हैं करने के लिए। आप SomeOtherColumn = 1 को सबसे तेज़ संभव तरीके से NULL पर इस कॉलम को सेट करना चाहते हैं।सबसे तेज तरीका बड़े पैमाने पर अद्यतन

जानवर बल UPDATE बहुत अच्छी तरह से यहाँ काम नहीं करता है क्योंकि यह बड़े अंतर्निहित लेनदेन बना सकते हैं और हमेशा के लिए ले जाएगा।

एक समय काम करता है पर 50K रिकॉर्ड के छोटे बैचों में अपडेट कर रहा लेकिन यह अभी भी 47 घंटे ले रहा है मांसल 32 कोर/64GB सर्वर पर पूरा करने के लिए।

क्या इस अद्यतन को तेजी से करने का कोई तरीका है? क्या कोई जादू प्रश्न संकेत/टेबल विकल्प हैं जो गति के बदले में कुछ और (जैसे concurrency) बलिदान करते हैं?

नोट: अस्थायी तालिका या अस्थायी कॉलम बनाना एक विकल्प नहीं है क्योंकि यह nvarchar(max) कॉलम में बहुत सारे डेटा शामिल हैं और इसलिए बहुत सारी जगहें खपत होती हैं!

पुनश्च: हाँ, SomeOtherColumn पहले से अनुक्रमित है।

+0

यह भी देखें: http://stackoverflow.com/questions/571750/make-sql-server-faster-at-manipulating-data-turn-off-transaction-logging –

+0

आप '50 के बैच रिकॉर्ड कैसे कर रहे हैं एक समय 'अद्यतन? क्या यह एक संग्रहीत प्रक्रिया के साथ है? यदि हां, तो क्या आप कोड डाल सकते हैं? – Fede

+0

@ user356004: पुन: पढ़ने पर मैं यह सोचने में मदद नहीं कर सकता कि या तो आपका सर्वर भारी भार में है या यह ठीक से स्थापित नहीं है: वह समय बहुत अधिक प्रतीत होता है। –

उत्तर

1

क्या आपने कुछ अन्य कॉलम पर इंडेक्स या आंकड़े रखने का प्रयास किया है?

+0

यदि प्रदर्शन समस्या है क्योंकि कोई अनुक्रमणिका नहीं है, और इसलिए अद्यतन करने के लिए पंक्तियों की पहचान करने के लिए एक तालिका स्कैन की आवश्यकता है, तो क्या कोई नई अनुक्रमणिका बनाने के लिए लंबे समय तक (या अधिक) नहीं लेगा और फिर अद्यतन जारी करेगा? –

+0

वास्तव में एक nvarchar (अधिकतम) कॉलम पर एक सूचकांक? – Paparazzi

3

आप Simple करने के लिए डेटाबेस वसूली मोड सेट लॉगिंग कम करने के लिए कर सकता है, लेकिन उत्पादन परिवेश के लिए पूर्ण प्रभाव पर विचार किए बिना ऐसा नहीं करते हैं।

तालिका में कौन से इंडेक्स मौजूद हैं? लगभग बैच अपडेट को देखते हुए। 50,000 पंक्तियां इतनी लंबी लगती हैं, मैं कहूंगा कि आपको एक इंडेक्स की आवश्यकता है।

0

'कुछ अन्य कॉलम' को अनुक्रमणित करने का प्रयास करें ... 50K रिकॉर्ड स्नैप में अपडेट होना चाहिए। यदि पहले से ही एक इंडेक्स मौजूद है तो देखें कि क्या इंडेक्स को पुनर्गठित करने की आवश्यकता है और इसके लिए आंकड़े एकत्र किए गए हैं।

0

आप पर्याप्त नहीं अंतरिक्ष के साथ उत्पादन परिवेश अपने सभी तालिकाओं नकल करने चला रहे हैं, मुझे विश्वास है कि आप मुसीबत के लिए अभी या बाद में देख रहे हैं।

आप SomeOtherColumn = 1 के साथ पंक्तियों की संख्या के बारे में कुछ जानकारी प्रदान करते हैं, शायद हम एक और तरीका सोच सकते हैं, लेकिन मेरा सुझाव है:

0) बैकअप अपनी मेज 1) सूचकांक ध्वज स्तंभ 2) सेट तालिका विकल्प "कोई लॉग tranctions" ... posible 3) के अपडेट

+0

बीटीडब्ल्यू ... क्या आपको इस प्रक्रिया को जीवन में एक से अधिक बार चलाने की आवश्यकता होगी? –

+1

आप "विकल्प लॉग ट्रांज़ेक्शन" के लिए टेबल विकल्प कैसे सेट करते हैं? – user356004

3

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

+0

निश्चित रूप से सुनिश्चित करें कि आप इंडेक्स छोड़ रहे हैं। अतीत में मेरे लिए चीजों को काफी कम कर दिया है। –

1

इससे वास्तव में मेरी मदद मिली। मैं इसके साथ 2 घंटे से 20 मिनट तक चला गया।

/* I'm using database recovery mode to Simple */ 
/* Update table statistics */ 

set transaction isolation level read uncommitted  

/* Your 50k update, just to have a measures of the time it will take */ 

set transaction isolation level READ COMMITTED 

मेरे अनुभव में, MSSQL 2005 में काम कर रहे, चलती हर रोज (स्वतः) 4 लाख एक अलग डेटाबेस लेता है में एक और मेज पर एक डेटाबेस में एक मेज से 46-बाइट-अभिलेख (कोई nvarchar (अधिकतम), हालांकि) क्वाडकोर 8 जीबी, 2 गीगा सर्वर में लगभग 20 मिनट और यह एप्लिकेशन प्रदर्शन को चोट नहीं पहुंचाता है। चलने से मेरा मतलब है चयन में शामिल करें और फिर हटाएं। सीपीयू का उपयोग कभी भी 30% से अधिक नहीं होता है, भले ही तालिका को हटाया जा रहा हो, 28 एम रिकॉर्ड हो और यह लगातार प्रति मिनट लगभग 4K डालने के लिए बनाता है लेकिन कोई अपडेट नहीं होता है। खैर, यह मेरा मामला है, यह आपके सर्वर लोड के आधार पर भिन्न हो सकता है।

पढ़ें अप्रतिबद्ध

"निर्दिष्ट करता है कि बयान (आपके अपडेट) पंक्तियों को अन्य लेन-देन से संशोधित किया गया है, लेकिन अभी तक प्रतिबद्ध नहीं पढ़ सकते हैं।" मेरे मामले में, रिकॉर्ड केवल पढ़ने के लिए हैं।

मुझे नहीं पता कि आरजी-tsql का मतलब क्या है लेकिन here आपको MSSQL में लेनदेन अलगाव स्तर के बारे में जानकारी मिल जाएगी।

+1

"आरजी" रेडगेट है, एक प्रायोजक कंपनी जो [tsql] टैग के परिणामों पर विज्ञापन कर रही है। – Corey

+1

हमेशा सावधान रहें और सुनिश्चित करें कि आप असम्बद्ध लेनदेन पढ़ने के प्रभावों को समझते हैं। हां, आपकी प्रक्रिया को वस्तुओं को हटाने से पहले प्रतिबद्ध करने के लिए खुले लेनदेन की प्रतीक्षा नहीं करनी पड़ेगी, लेकिन निश्चित रूप से यदि लेनदेन पूरा नहीं किया जाता है तो इसका मतलब यह होगा कि आपने पंक्ति को गलत तरीके से हटा दिया है !! – Cobusve

7

सबकुछ से मैं देख सकता हूं कि आपकी समस्याएं इंडेक्स से संबंधित नहीं हैं।

कुंजी तथ्य यह है कि अपने nvarchar (अधिकतम) क्षेत्र डेटा की "बहुत सारे" शामिल में हो रहा है। इस अद्यतन को करने के लिए एसक्यूएल को क्या करना है इसके बारे में सोचें।

के बाद से स्तंभ आप अद्यतन कर रहे हैं की संभावना 8000 से अधिक वर्ण यह ऑफ पेज है, जो इस कॉलम को पढ़ने जब यह शून्य नहीं है में अतिरिक्त प्रयास का तात्पर्य संग्रहीत होती है।

जब आप 50000 अपडेट एसक्यूएल आदेश यह संभव है किसी भी समस्याओं के मामले में वापस रोल करने के लिए एक अंतर्निहित लेनदेन में इस जगह के लिए है का एक बैच चलाते हैं। वापस रोल करने के लिए इसे लेनदेन लॉग में कॉलम के मूल मान को स्टोर करना होगा।

मानते हैं (सादगी के लिए) प्रत्येक स्तंभ में औसत 10,000 बाइट डेटा होते हैं, जिसका अर्थ है कि 50,000 पंक्तियों में लगभग 500 एमबी डेटा होगा, जिसे अस्थायी रूप से (सरल वसूली मोड में) या स्थायी रूप से संग्रहीत किया जाना चाहिए (पूरी तरह से पुनर्प्राप्ति में) मोड)।

वहाँ लॉग अक्षम करना के रूप में यह डेटाबेस अखंडता के साथ समझौता होगा कोई रास्ता नहीं है।

मैंने अपने कुत्ते के धीमे डेस्कटॉप पर एक त्वरित परीक्षण चलाया, और 10,000 तक चलने वाले बैच भी धीमे हो जाते हैं, लेकिन आकार को 1000 पंक्तियों तक लाया जाता है, जो लगभग 10 एमबी के अस्थायी लॉग आकार का तात्पर्य है, केवल अच्छी तरह से काम करता है।

मैंने 350,000 पंक्तियों वाली एक तालिका लोड की और अद्यतन के लिए उनमें से 50,000 चिह्नित किए। यह लगभग 4 मिनट में पूरा हुआ, और चूंकि यह रैखिक रूप से स्केल करता है, इसलिए आप अपने कुत्ते धीमे डेस्कटॉप पर अपने पूरे 5 मिलियन पंक्तियों को अपने 1 प्रोसेसर 2 जीबी डेस्कटॉप पर लगभग 6 घंटों में अपडेट करने में सक्षम होना चाहिए, इसलिए मैं आपके बीफ़ी सर्वर पर समर्थित कुछ बेहतर उम्मीद करूँगा SAN या कुछ द्वारा।

आप एक का चयन के रूप में अपने अद्यतन बयान चलाने केवल प्राथमिक कुंजी और बड़े nvarchar स्तंभ का चयन, और इस रूप में तेजी से आप उम्मीद के रूप में चलाता है सुनिश्चित करने के लिए कर सकते हैं।

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

एक अनुकूलन के रूप में आप यह सुनिश्चित करना चाहिए कि हस्तांतरण लॉग बार की तलाश को कम करने के डेटा से एक अलग भौतिक डिस्क/डिस्क समूह पर हैं।

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