OracleBulkCopy विशेष रूप से क्या करता है, और मैं इसके प्रदर्शन को कैसे अनुकूलित कर सकता हूं?


14

बारीकियों को संक्षेप में बताने के लिए: हमें लगभग 5 मिलियन पंक्तियों को एक विक्रेता (ओरेकल) डेटाबेस में बदलने की आवश्यकता है। OracleBulkCopy(ODP.NET) का उपयोग करके 500k पंक्तियों के बैचों के लिए सब कुछ बहुत अच्छा हो जाता है , लेकिन जब हम 5M तक स्केल करने की कोशिश करते हैं, तो 1M मार्क को हिट करते ही प्रदर्शन क्रॉल करना शुरू कर देता है, क्रमिक रूप से धीमा हो जाता है क्योंकि अधिक पंक्तियाँ लोड होती हैं, और अंततः 3 घंटे या तो के बाद बाहर बार।

मुझे संदेह है कि यह मेज पर एक प्राथमिक कुंजी से संबंधित है, लेकिन मैं जानकारी के लिए ओरेकल मंचों और स्टैक ओवरफ्लो को पीछे छोड़ रहा हूं और बहुत कुछ जो मैं विरोधाभास पढ़ रहा हूं, वह भी (बहुत सारे पद एक -दूसरे के विपरीत प्रतीत होते हैं ) । मैं उम्मीद कर रहा हूं कि कोई व्यक्ति प्रक्रिया के बारे में कुछ करीबी सवालों पर सीधे रिकॉर्ड सेट कर सकता है:

  1. क्या OracleBulkCopyक्लास पारंपरिक या प्रत्यक्ष-पथ लोडिंग का उपयोग करता है ? क्या कोई तरीका है जिससे मैं इसकी पुष्टि कर सकता हूं, एक तरीका या दूसरा?

  2. यह मानते हुए कि यह प्रत्यक्ष-पथ लोडिंग का उपयोग करता है : क्या यह सच है कि ओरेकल लोड के दौरान सभी इंडेक्सों को स्वचालित रूप से अनुपयोगी बना देता है और उन्हें ऑनलाइन बाद में वापस रखता है? मैंने इस आशय के कई कथन पढ़े हैं, लेकिन फिर से, इसकी पुष्टि नहीं कर सकता।

  3. यदि # 2 सत्य है, तो क्या इससे कोई फर्क पड़ता है कि मैं थोक कॉपी ऑपरेशन शुरू करने से पहले तालिका में कौन से सूचकांक हैं? यदि हां, तो क्यों?

  4. # 3 से संबंधित, क्या कोई व्यावहारिक अंतर है, सामान्य रूप से, एक अनुपयोगी सूचकांक के साथ थोक लोडिंग के बीच बनाम वास्तव में लोड से पहले सूचकांक को गिराना और बाद में इसे फिर से बनाना है?

  5. यदि # 2 सही नहीं है, या यदि कुछ ऐसे कैविएट हैं जिन्हें मैं नहीं समझ पा रहा हूं, तो क्या इससे थोक भार से पहले सूचकांक को स्पष्ट रूप से अनुपयोगी बनाने के लिए कोई फर्क पड़ेगा और फिर स्पष्ट रूप से बाद में इसका पुनर्निर्माण करना होगा?

  6. क्या इंडेक्स बिल्ड के अलावा भी कुछ और है, जिससे उत्तरोत्तर धीमी गति से बढ़ने के लिए थोक कॉपी ऑपरेशन हो सकता है क्योंकि अधिक से अधिक रिकॉर्ड जोड़े जाते हैं? (शायद लॉगिंग के साथ कुछ करना है, हालांकि मुझे उम्मीद है कि थोक संचालन लॉग नहीं हैं?)

  7. अगर वास्तव में पीके / इंडेक्स को छोड़ने से अलग प्रदर्शन करने का कोई दूसरा तरीका नहीं है , तो मैं यह सुनिश्चित करने के लिए क्या कदम उठा सकता हूं कि इंडेक्स पूरी तरह से गायब न हो, यानी अगर डेटाबेस से कनेक्शन खो गया है इस प्रक्रिया के बीच में?


साइड नोट: कॉपी किया जा रहा डेटा पहले से ही PK के अनुसार क्रमबद्ध क्रम में है, जो कि तालिका का एकमात्र सूचकांक है।
हारून पकड़ा गया

क्या आप स्रोत से डेटा पढ़ने के लिए एक DataReader का उपयोग कर रहे हैं?
bernd_k

@bernd_k: नहीं, मेमोरी से पूरी तरह लोड हो रहा है। यह निश्चित रूप से स्रोत नहीं है यही समस्या है।
हारून

जवाबों:


14

पढ़ने और प्रयोग के कुछ और दिन और मैं (अधिकतर) इनमें से बहुत से उत्तर देने में सक्षम था:

  1. मैंने इसे ODP.NET दस्तावेज में दफन किया (विडंबना यह है कि OracleBulkCopyडॉक्स में नहीं ):

    ODP.NET बल्क कॉपी फीचर एक डायरेक्ट पाथ लोड एप्रोच का उपयोग करता है, जो कि ओरेकल एसक्यूएल * लोडर के समान नहीं है। डायरेक्ट लोडिंग का उपयोग करना पारंपरिक लोडिंग (पारंपरिक एसक्यूएल INSERTस्टेटमेंट्स का उपयोग करके ) से तेज है ।

    तो ऐसा प्रतीत होता है कि यह प्रत्यक्ष पथ का उपयोग करता है

  2. यह मैं एक बड़ी थोक कॉपी ऑपरेशन और SQL डेवलपर से सूचकांक गुण प्राप्त करके सत्यापित करने में सक्षम था। सूचकांक की थी के रूप में दिखाई UNUSABLEजबकि थोक प्रतिलिपि प्रगति पर था। हालाँकि , मुझे यह भी पता चला है कि OracleBulkCopy.WriteToServerअगर राज्य में सूचकांक शुरू होता है UNUSABLE, तो इसे चलाने से इंकार कर दिया जाएगा , इसलिए स्पष्ट रूप से यहां अधिक चल रहा है, क्योंकि यदि यह सूचकांक को अक्षम करने और पुनर्निर्माण के रूप में सरल था, तो इसे प्रारंभिक स्थिति की परवाह नहीं करनी चाहिए।

  3. यह विशेष रूप से एक अंतर बनाता है अगर सूचकांक भी एक बाधा है । ऊपर दिए गए दस्तावेज़ में इस छोटे रत्न को मिला:


    ओरेकल बल्क कॉपी के दौरान सक्षम बाधाएं , निम्नलिखित बाधाएं डिफ़ॉल्ट रूप से स्वचालित रूप से सक्षम होती हैं:

    • NOT NULL
    • UNIQUE
    • PRIMARY KEY (अनुपस्थित कॉलम पर अद्वितीय-अवरोध)

    NOT NULLस्तंभ सरणी निर्माण समय में बाधाओं की जाँच की जाती है। कोई भी पंक्ति जो NOT NULLबाधा का उल्लंघन करती है उसे अस्वीकार कर दिया जाता है।

    UNIQUEजब इंडेक्स को लोड के अंत में फिर से बनाया जाता है, तो बाधाओं को सत्यापित किया जाता है। यदि सूचकांक एक UNIQUEबाधा का उल्लंघन करता है, तो सूचकांक को एक सूचकांक में नहीं छोड़ा जाता है ।

    दस्तावेज़ लोड के दौरान क्या होता है, इस बारे में थोड़ा धुंधला है , विशेष रूप से प्राथमिक कुंजी के साथ, लेकिन एक बात बिल्कुल निश्चित है - यह एक के बिना एक प्राथमिक कुंजी बनाम के साथ अलग तरह से व्यवहार करता है । चूँकि आप ख़ुशी-ख़ुशी आपको अनुक्रमणिका बाधाओं का उल्लंघन करने देंगे (और जब यह किया जाता है तो सूचकांक को राज्य में डाल सकते हैं ), मेरा कूबड़ यह है कि यह थोक प्रतिलिपि के दौरान पीके सूचकांक का निर्माण कर रहा है , लेकिन बाद में इसे मान्य नहीं किया जा सकता है।OracleBulkCopyUNUSABLE

  4. मुझे यकीन नहीं है कि क्या अंतर ओरेकल के भीतर है या केवल एक क्विक है OracleBulkCopy। जूरी अभी भी इस पर बाहर है।

  5. OracleBulkCopyयदि UNUSABLEराज्य में एक सूचकांक शुरू में है , तो एक अपवाद फेंक देंगे , तो यह वास्तव में एक लूट बिंदु है।

  6. वहाँ तो कर रहे हैं अन्य कारकों, अनुक्रमित (और विशेष रूप पीके अनुक्रमित) अभी भी सबसे महत्वपूर्ण, जैसा कि मैंने पर आउट हो जाते हैं:

  7. एक ही स्कीमा (उपयोग करके CREATE AS) के साथ एक वैश्विक अस्थायी तालिका बनाना , फिर अस्थायी तालिका में कॉपी करना, और अंत INSERTमें अस्थायी तालिका से वास्तविक तालिका में एक पुराना करना । चूंकि अस्थायी तालिका में कोई इंडेक्स नहीं है, बल्क कॉपी बहुत तेज़ी से होती है, और अंतिम INSERTभी तेज़ है क्योंकि डेटा पहले से ही एक तालिका में है (मैंने अभी तक अपेंडेंट संकेत की कोशिश नहीं की है, क्योंकि 5M पंक्ति तालिका से टेबल कॉपी पहले से ही 1 मिनट से कम समय लगता है)।

    मैं इस तरह से अस्थायी तालिका स्थान का उपयोग कर (ab) के संभावित प्रभावों के बारे में अभी तक निश्चित नहीं हूं, लेकिन अभी तक इसने मुझे कोई परेशानी नहीं दी है, और यह या तो पंक्तियों के भ्रष्टाचार को रोकने के विकल्प के मुकाबले अधिक सुरक्षित है। या अनुक्रमणिका।

    इस की सफलता भी स्पष्ट रूप से दर्शाती है कि पीके सूचकांक समस्या है, क्योंकि यह अस्थायी तालिका और स्थायी तालिका के बीच एकमात्र व्यावहारिक अंतर है - दोनों ने प्रदर्शन परीक्षणों के दौरान शून्य पंक्तियों के साथ शुरू किया।

निष्कर्ष: ODP.NET का उपयोग करके एक अनुक्रमित ओरेकल तालिका में लगभग 100k पंक्तियों से अधिक कॉपी करने की कोशिश न करें। या तो सूचकांक को छोड़ दें (यदि आपको वास्तव में इसकी आवश्यकता नहीं है) या डेटा को एक अलग (गैर-अनुक्रमित) तालिका में "प्रीलोड" करें ।


मुझे प्राथमिक कुंजी बाधाओं की जाँच के बारे में निश्चित नहीं है। मैं एक ही डेटा को Oracle तालिका में 2 बार थोक में डालने के लिए खुश था और 2 * अनुलिपि पंक्तियों का चयन करता है। उस स्थिति में डिलीट संभव नहीं है, लेकिन ट्रंकट टेबल एक साफ स्थिति में वापस आने में मदद करता है।
bernd_k

@bernd_k: Deleteसंभव नहीं है क्योंकि सूचकांक है UNUSABLE। यह बाधा की जाँच का एक परिणाम है जो थोक प्रतिलिपि के अंत में होता है।
Aaronaught

मेरे पास एक PowerShell स्क्रीप्ट चल रहा है, जिसमें SQL सर्वर डेटा रीडर से ऑरेकल डेटाबेस में बल्कॉपी कॉलिंग है, सभी प्राथमिक कुंजी के साथ लक्ष्य तालिकाओं और मुझे 205278 पंक्तियों के साथ तालिकाओं के साथ कोई समस्या नहीं है। लेकिन मैं विवरण तालिका भरने से पहले पहले मास्टर तालिकाओं को पूरा करने के लिए बहुत सावधान हूं। मैंने टेबल पर किसी भी अन्य इंडेक्स को नहीं हटाया और जब टेबल शुरू में खाली थी तो मुझे कोई समस्या नहीं थी।
bernd_k 15

@bernd_k: हां, मुझे उस वॉल्यूम पर या तो बहुत अधिक समस्याएं नहीं थीं (मेरा अंतिम पैराग्राफ देखें)। जब आप लाखों में पहुँचते हैं तो यह भयानक हो जाता है। इसके अलावा एक अंतर हो सकता है यदि आप प्रत्येक थोक प्रतिलिपि के कुछ समय बाद तालिका खाली करते हैं (यह एक खाली नहीं हो जाता है, यह संलग्न हो जाता है, और आप जानते हैं कि अनुक्रमित कैसे धीमी हो जाती हैं क्योंकि वे बड़े हो जाते हैं)।
हारून

शायद यह मदद करता है जब आप एकalter session set skip_unusable_indexes = true;
Wernfried Domscheit

1

यहां ओरेकल का एक लेख है जो बताता है कि कब बल्क इंसर्ट का इस्तेमाल करना फायदेमंद होगा या कब नहीं। इसके अलावा, डेटाबेस स्तर पर क्या होता है, इस पर एक अंतर्दृष्टि है।

http://docs.oracle.com/cd/B28359_01/server.111/b28319/ldr_modes.htm


3
कड़ियाँ सड़ जाती हैं; आप अपने उत्तर में लिंक से प्रासंगिक जानकारी शामिल करना चाह सकते हैं।
21
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.