2013-08-28 6 views
5

मुझे एक बड़ी पीएल/एसक्यूएल प्रक्रिया के हिस्से के रूप में एक सीएलओबी चर पर निर्मित रीप्लेस समारोह का उपयोग करने की आवश्यकता है। मैं ओरेकल 11 जी आर 2 का उपयोग कर रहा हूं और फ़ंक्शन ठीक काम करता है, जिसमें यह आवश्यकतानुसार प्रतिस्थापन करता है, लेकिन प्रक्रिया चलती है (प्रक्रिया के लिए लगभग 2.5 मिलियन रिकॉर्ड होते हैं), यह बुरी तरह धीमा हो जाता है - जैसा कि:सीएलओबी पर REPLACE फ़ंक्शन का उपयोग क्यों करते हैं CACHE_LOBS में वृद्धि ...?

  • पहले 20,000 रिकॉर्ड: ~ 12 मिनट
  • दूसरा 20,000 रिकॉर्ड: ~ 24 मिनट
  • तीसरे 20,000 रिकॉर्ड: ~ 37 मिनट
  • चौथे 20,000 रिकॉर्ड: ~ 52 मिनट
  • आदि ...

ऑपरेशन के दौरान वी $ TEMPORARY_LOBS की जांच से पता चलता है कि प्रत्येक पंक्ति के साथ सीएसीएचआईएलबीबीएस के लिए मूल्य बढ़ता है - मेरी धारणा यह है कि इसका मतलब यह है कि LOBS (इस मामले में CLOBS) से जुड़ी मेमोरी का उपयोग होने के बाद रिलीज़ नहीं हो रहा है ...?

पीएल/एसक्यूएल डीबगर का उपयोग करके कोड के माध्यम से कदम उठाने से पता चलता है कि प्रत्येक कॉल के लिए RECHLACE फ़ंक्शन पर CACHE_LOBS के लिए 2 से बढ़ता है। फ़ंक्शन कॉल की तर्ज पर कर रहे हैं:

clobRTFText   CLOB; 
... 
dbms_lob.createtemporary(clobRTFText, TRUE, dbms_lob.call); 
... 
clobRTFText := REPLACE(clobRTFText, '<CR>', '\par '); <== Causes CACHE_LOBS to increase by 2 
... 
dbms_lob.freetemporary(clobRTFText); <== Doesn't seem to cause CACHE_LOBS to decrease 

जैसे कि कोड की तीसरी पंक्ति के ऊपर फ्लाई पर आगे CLOB चर पैदा कर रही है यह। क्या ऐसा इसलिए है क्योंकि एक VARCHAR2 पैरामीटर की अपेक्षा रखने वाले REPLACE फ़ंक्शन के कारण कुछ प्रकार का अंतर्निहित प्रकार रूपांतरण होता है? मैंने "clobRTFText: = REPLACE ... आदि" के बजाय dbms_lob.copy का उपयोग करने का प्रयास किया है, लेकिन यह वास्तव में खराब था (यानी CACHE_LOBS भी तेज हो गया)। जो भी कारण है, dbms_lob.freetemporary को कॉल CACHE_LOBS के मान में कोई फर्क नहीं पड़ता है।

मैं Oracle दस्तावेज की PL/SQL Semantics for LOBs अनुभाग के माध्यम से चले गए हैं - यह तरीका CLOB का उल्लेख है और VARCHAR2 चर में निर्मित कार्यों में इस्तेमाल किया जा सकता है, लेकिन मैं तो संभवतः कर अतिरिक्त स्मृति के उपयोग के कारण के बारे में कुछ भी नहीं मिल सकता है।

क्या किसी के पास कोई विचार है कि यह क्यों हो रहा है या मैं इसे कैसे कर सकता हूं (यानी सीएलओबी के साथ रीप्लेस का उपयोग करें) बिना स्मृति को जारी करने में विफल रहता है (मान लीजिए कि वास्तव में क्या हो रहा है)?

धन्यवाद

+1

क्या आपने लॉब्स को कैश नहीं करने की कोशिश की है? जैसा कि 'dbms_lob.createtemporary (clobRTFText, FALSE, dbms_lob.call) में है;' –

+2

मैं जो भी दिखाया गया है उस पर लूपिंग के कुछ बदलावों के साथ एक ही चीज़ नहीं देख रहा हूं; 'lob_cache' गिनती' प्रतिस्थापन 'के लिए 2 से बढ़ जाती है, लेकिन केवल दायरे के लिए पहली बार होती है। मैं 3 या 4 से ऊपर का मूल्य कभी नहीं देखता हूं। संभवतः मैं कुछ अलग कर रहा हूं, तो क्या आप विस्तार कर सकते हैं कि यह कैसे कहा जा रहा है और यह और क्या कर रहा है? आदर्श रूप से एक पूर्ण कट-डाउन संस्करण जो व्यवहार दिखाता है। –

+1

क्या आपके पास एकाधिक लोकेटर हैं? [DBMS_LOB] के दस्तावेज़ों से (http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/d_lob.htm#i1015757): _ अस्थायी LOB की एक प्रति बनाई गई है यदि उपयोगकर्ता अस्थायी LOB को संशोधित करता है जबकि एक और लोकेटर भी इसे इंगित कर रहा है। लोकेटर जिस पर एक संशोधन किया गया था अब अस्थायी LOB._ की एक नई प्रति को इंगित करता है – user272735

उत्तर

1

यह प्रक्रियात्मक रूप से क्यों करें? ऐसा लगता है कि एक घोषणात्मक दृष्टिकोण आवश्यकताओं को पूरा करता है।

UPDATE clob_table SET clob_column = REPLACE(clob_column, '<CR>', '\par ');

आप जो कुछ भी WHERE खंड है कि आप सूट आपूर्ति कर सकते हैं।

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