ओरेकल के भीतर, एसक्यूएल वर्चुअल मशीन (वीएम) और पीएल/एसक्यूएल वीएम के माध्यम से पीएल/एसक्यूएल इंजन का उपयोग करता है। जब आपको एक वीएम से दूसरे वीएम में स्थानांतरित करने की आवश्यकता होती है, तो आपको एक संदर्भ शिफ्ट की लागत लगती है। व्यक्तिगत रूप से, उन संदर्भ परिवर्तन अपेक्षाकृत तेज़ होते हैं, लेकिन जब आप पंक्ति-दर-पंक्ति प्रसंस्करण कर रहे होते हैं, तो वे आपके कोड के खर्च के एक महत्वपूर्ण अंश के लिए खाते में जोड़ सकते हैं। जब आप थोक बाइंड का उपयोग करते हैं, तो आप एक वीएम से डेटा की कई पंक्तियों को एक संदर्भ में बदलते हैं, जिससे संदर्भ परिवर्तनों की संख्या में काफी कमी आती है, जिससे आपका कोड तेज़ी से बढ़ जाता है।
उदाहरण के लिए, एक स्पष्ट कर्सर लें। यदि मैं यह
DECLARE
CURSOR c
IS SELECT *
FROM source_table;
l_rec source_table%rowtype;
BEGIN
OPEN c;
LOOP
FETCH c INTO l_rec;
EXIT WHEN c%notfound;
INSERT INTO dest_table(col1, col2, ... , colN)
VALUES(l_rec.col1, l_rec.col2, ... , l_rec.colN);
END LOOP;
END;
की तरह कुछ लिखने तो हर बार जब मैं लाने पर अमल, मैं
- हूँ एसक्यूएल वीएम
- लिए PL/SQL वीएम से एक संदर्भ पारी एसक्यूएल वीएम पूछ प्रदर्शन कर्सर निष्पादित करने के लिए डेटा के अपने एकल पंक्ति वापस जाने के लिए डेटा
- PL/SQL वी एम के लिए एसक्यूएल वीएम से दूसरे संदर्भ पारी प्रदर्शन वापस की अगली पंक्ति उत्पन्न करने के लिए
और हर बार जब मैं एक पंक्ति डालता हूं, तो मैं वही कर रहा हूं। मैं पीएल/एसक्यूएल वीएम से एसक्यूएल वीएम में डेटा की एक पंक्ति को शिप करने के लिए एक संदर्भ शिफ्ट की लागत का खर्च कर रहा हूं, एसक्यूएल को INSERT
कथन निष्पादित करने के लिए कह रहा है, और उसके बाद पीएल/एसक्यूएल पर एक और संदर्भ शिफ्ट की लागत लगाना।
यदि source_table
में 1 मिलियन पंक्तियां हैं, तो यह 4 मिलियन संदर्भ बदलाव है जो संभवतः मेरे कोड के विलुप्त समय के उचित अंश के लिए जिम्मेदार होगा। यदि, दूसरी तरफ, मैं BULK COLLECT
को 100 के LIMIT
के साथ करता हूं, तो मैं पीएल/एसक्यूएल में संग्रह में एसक्यूएल वीएम से डेटा की 100 पंक्तियों को पुनर्प्राप्त करके अपने संदर्भ परिवर्तनों का 99% समाप्त कर सकता हूं, हर बार जब मैं लागत लेता हूं एक संदर्भ शिफ्ट और प्रत्येक बार जब मैं एक संदर्भ शिफ्ट लेता हूं, गंतव्य तालिका में 100 पंक्तियां डालता हूं।
मेरे कोड को फिर से लिखने कर सकते हैं हर बार जब मैं लाने पर अमल थोक संचालन
DECLARE
CURSOR c
IS SELECT *
FROM source_table;
TYPE nt_type IS TABLE OF source_table%rowtype;
l_arr nt_type;
BEGIN
OPEN c;
LOOP
FETCH c BULK COLLECT INTO l_arr LIMIT 100;
EXIT WHEN l_arr.count = 0;
FORALL i IN 1 .. l_arr.count
INSERT INTO dest_table(col1, col2, ... , colN)
VALUES(l_arr(i).col1, l_arr(i).col2, ... , l_arr(i).colN);
END LOOP;
END;
का उपयोग करना अब, मैं संदर्भ बदलाव का एक सेट के साथ मेरे संग्रह में डेटा की अधिकतम 100 पंक्तियां पुनः प्राप्त। और हर बार जब मैं अपना FORALL
सम्मिलित करता हूं, तो मैं संदर्भ पंक्तियों के एक सेट के साथ 100 पंक्तियां डाल रहा हूं। यदि source_table
में 1 मिलियन पंक्तियां हैं, तो इसका मतलब है कि मैं 4 मिलियन संदर्भ बदलावों से 40,000 संदर्भ परिवर्तनों में गया हूं। यदि संदर्भ परिवर्तनों के लिए जिम्मेदार ठहराया गया है, तो मेरे कोड के विलुप्त समय का 20%, मैंने बीत चुके समय के 1 9 .8% को समाप्त कर दिया है।
संदर्भ परिवर्तनों की संख्या को और कम करने के लिए आप LIMIT
के आकार को बढ़ा सकते हैं लेकिन आप जल्दी से कम रिटर्न के कानून को दबाते हैं। यदि आपने 100 के बजाय 1000 के LIMIT
का उपयोग किया है, तो आप 99% की बजाय संदर्भ परिवर्तनों का 99.9% खत्म कर देंगे। इसका मतलब यह होगा कि आपका संग्रह 10x अधिक पीजीए मेमोरी का उपयोग कर रहा था, हालांकि। और यह हमारे hypothetical उदाहरण में केवल 0.18% अधिक समय बीत जाएगा। आप बहुत जल्दी उस बिंदु तक पहुंचते हैं जहां अतिरिक्त मेमोरी आप अतिरिक्त संदर्भ बदलावों को समाप्त करके सहेजने से अधिक समय जोड़ती है। आम तौर पर, LIMIT
कहीं 100 से 1000 के बीच मीठा स्थान होने की संभावना है।
बेशक
, इस उदाहरण में, यह और अधिक कुशल अभी भी सभी संदर्भ बदलाव को खत्म करने और एक एकल एसक्यूएल बयान
INSERT INTO dest_table(col1, col2, ... , colN)
SELECT col1, col2, ... , colN
FROM source_table;
यह केवल मतलब होगा में PL/SQL का सहारा लेना में सब कुछ करना होगा पहली जगह यदि आप स्रोत तालिका से डेटा के किसी प्रकार का हेरफेर कर रहे हैं जिसे आप SQL में उचित रूप से कार्यान्वित नहीं कर सकते हैं।
इसके अतिरिक्त, मैंने जानबूझकर मेरे उदाहरण में एक स्पष्ट कर्सर का उपयोग किया। यदि आप ओरेकल के हाल के संस्करणों में अंतर्निहित कर्सर का उपयोग कर रहे हैं, तो आपको 10012 के LIMIT
के साथ BULK COLLECT
का लाभ मिलता है। एक और स्टैक ओवरफ्लो प्रश्न है जो रिश्तेदार performance benefits of implicit and explicit cursors with bulk operations पर चर्चा करता है जो उन विशेष झुर्रियों के बारे में अधिक जानकारी देता है।
आपकी आखिरी वाक्य थोड़ी सी धोखा दे रही है। बल्क संदर्भ स्विच केवल एक बार होता है, हालांकि यह अभी भी होता है। – viper