2011-05-14 13 views
7

में बहुत बड़ी तालिकाओं का अद्यतन या मेर्ज मुझे एक बहुत बड़े (300 एम रिकॉर्ड) और विस्तृत TABLE1 का दैनिक अपडेट करने की आवश्यकता है। अद्यतनों के लिए स्रोत डेटा किसी अन्य तालिका UTABLE में स्थित है जो TABLE1 की पंक्तियों में 10% -25% है लेकिन यह संकीर्ण है। दोनों तालिकाओं में प्राथमिक कुंजी के रूप में record_id है।SQL सर्वर

वर्तमान में, मैं TABLE1 निम्नलिखित दृष्टिकोण का उपयोग कर पुनः हूँ:

<!-- language: sql --> 
    1) SELECT (required columns) INTO TMP_TABLE1 
    FROM TABLE1 T join UTABLE U on T.record_id=U.record_id 
    2) DROP TABLE TABLE1 
    3) sp_rename 'TMP_TABLE1', 'TABLE1' 

हालांकि इस अपने सर्वर (SQL सर्वर के लिए रैम 60GB) पर लगभग 40 मिनट लगते हैं। मैं 50% प्रदर्शन लाभ प्राप्त करना चाहता हूं - मैं अन्य विकल्पों का प्रयास कैसे कर सकता हूं?

  1. MERGE और UPDATE - तरह नीचे कोड तेजी से केवल एक बहुत छोटा UTABLE तालिका के लिए काम करता है कुछ - पूर्ण आकार में, सब कुछ सिर्फ लटकी हुई है:

    <!-- language: SQL --> 
    MERGE TABLE1 as target 
    USING UTABLE as source 
    ON target.record_id = source.record_id 
        WHEN MATCHED THEN 
        UPDATE SET Target.columns=source.columns 
    
  2. मैंने सुना है कि मैं एक बैच प्रदर्शन कर सकते हैं ROWCOUNT का उपयोग करके मेर्ज - लेकिन मुझे नहीं लगता कि यह 300 एम पंक्ति तालिका के लिए पर्याप्त तेज़ हो सकता है।

  3. कोई भी SQL क्वेरी संकेत जो मददगार हो सकता है?

+0

के दौरान इंडेक्स का पुनर्निर्माण करने के लिए अतिरिक्त कार्य होगा, क्या आप क्वेरी प्लान पोस्ट कर सकते हैं? –

+0

हाय @ क्रिस, क्वेरी प्लान मृत सरल है: ** 1 ** टेबल स्कैन टैबलेट 1, ** 2 ** टेबल स्कैन यूटबल, ** 3 ** हैश जॉइन, ** 4 ** मेर्ज। पहला और अंतिम चरण 90% समय ले रहा है। हालांकि मैं पहले ही समझ चुका हूं कि मेरे प्रश्न को कैसे हल किया जाए - कृपया मेरा अपना जवाब देखें। –

उत्तर

5

वास्तव में मैं इस तरह के एक क्वेरी के लिए सामान्य सुझाव पता चला है: आइडिया एसक्यूएल मर्ज का उपयोग करने या अद्यतन एक बहुत चालाक एक है लेकिन यह विफल रहता है, जब हम कई रिकॉर्ड (यानी 75M) एक बड़ा और व्यापक में अद्यतन करने की आवश्यकता तालिका (यानी 240 एम)।

नीचे दी गई क्वेरी की क्वेरी प्लान को देखते हुए हम कह सकते हैं कि TABLE SCAN टैबलेट 1 और अंतिम MERGE 90% समय ले रहे हैं।

MERGE TABLE1 as Target 
USING UTABLE as source 
ON Target.record_id = source.record_id 
WHEN MATCHED AND (condition) THEN 
    UPDATE SET Target.columns=source.columns 

तो आदेश मर्ज का उपयोग में हम की जरूरत है:

  1. पंक्तियों की संख्या हम अद्यतन और सही ढंग से एसक्यूएल सर्वर के लिए इस जानकारी को पारित करने की जरूरत को कम करें। यह UTABLE छोटा या अतिरिक्त condition निर्दिष्ट करके किया जा सकता है जो भाग को विलय करने के लिए संक्षिप्त करता है।
  2. सुनिश्चित करें कि भाग में विलय होने के लिए स्मृति में फिट बैठता है अन्यथा क्वेरी धीमी गति से चलती है। TABLE1 बनाने से मेरे वास्तविक प्रश्न समय को 11 घंटे से 40 मिनट तक कम कर दिया गया।

मार्क उल्लेख किया है आप UPDATE सिंटैक्स का उपयोग करें और हिस्सा संकीर्ण करने के लिए WHERE खंड का उपयोग कर सकते होने वाली विलय कर दिया - यह एक ही परिणाम प्राप्त होंगे। कृपया TABLE1 अनुक्रमणित करने से बचें क्योंकि इससे MERGE

6

सबसे पहले मुझे पता चल जाएगा कि आपकी बाधा कहां है - क्या आपका सीपीयू पेग्ड या निष्क्रिय है? दूसरे शब्दों में - क्या आपका आईओ उपप्रणाली लोड को सही तरीके से संभालने में सक्षम है?

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

क्या आपको एक मेरिज करने की आवश्यकता है - जो मैं देख सकता हूं उससे एक सरल अपडेट पर्याप्त होना चाहिए। उदाहरण:

UPDATE 
    TABLE1 
SET 
    ColumnX = UTABLE.ColumnX 
    ... 
FROM 
    TABLE1 
INNER JOIN 
    UTABLE ON TABLE1.record_id = UTABLE.record_id 

आप ROWCOUNT का उपयोग कर अद्यतन लेकिन यह है कि निष्पादन में तेजी लाने के नहीं होंगे अप बैच, यह केवल समग्र लॉकिंग को कम करने के साथ मदद कर सकें।

इसके अलावा - तालिका में आपके पास किस प्रकार की अनुक्रमणिका है? अद्यतन से पहले इंडेक्स को अक्षम करना और फिर बाद में स्क्रैच से पुनर्निर्माण करना (केवल गैर-क्लस्टर) हो सकता है।

+0

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

+1

+1 ग्रेट उत्तर। समझ में नहीं आता क्यों किसी ने इसे अभी तक ऊपर नहीं उठाया। –