2012-01-05 16 views
12

मेरे पास oracle stored proc है जिसे मेरे जावा प्रोग्राम से कॉल करने की आवश्यकता है। मैंने संग्रहित प्रो को पैरामीटर पास करने के लिए CallableStatement का उपयोग किया था। मैं ऑरैकल पतली चालक का उपयोग कर रहा हूं (प्रासंगिक जेएनडीआई एंट्री के खिलाफ वेब लॉजिक सर्वर में कॉन्फ़िगर किया गया)। इस संग्रहित प्रो में कोई आउट मान नहीं है। यह संग्रहीत proc एक संख्यात्मक मान स्वीकार करता है और प्राप्त मूल्य के आधार पर डीबी में बहुत से अद्यतन करता है।तैयार स्टेमेंटमेंट, कॉल करने योग्य स्टेटमेंट और प्रदर्शन विचार

मुझे एक कनेक्शन ऑब्जेक्ट मिलता है और फिर इस संग्रहित प्रो को लूप में कॉल करें (20 संख्याओं को पार करने के लिए 20 बार)। जब मैं सीधे इस संग्रहित प्रो को ऑरैक क्लाइंट से कॉल करता हूं, तो निष्पादन 2-3 सेकंड में पूरा हो जाता है। हालांकि व्यवहार मेरे जावा कोड से अनुमानित नहीं है। कुछ कॉल पूर्ण होने के लिए 30-40 सेकंड भी लेते हैं।

मैंने के बजाय PreparedStatement का उपयोग करने की कोशिश की और मामूली प्रदर्शन सुधार (हालांकि व्यवहार अभी भी असंगत है) देख सकता है।

  1. उस में मेरे मामले का उपयोग करने के PreparedStatement बजाय CallableStatement यह देखते हुए कि storedproc किसी भी बाहर पैरामीटर नहीं है ठीक है?
  2. क्या कोई कारण है कि PreparedStatement पर कुछ प्रदर्शन लाभ CallableStatement पर है या क्या ऐसा कुछ है जिसे मैंने गलत तरीके से देखा होगा?
  3. क्या इस प्रदर्शन समस्या को हल करने के लिए कोई बेहतर तरीका है?
+3

क्या आप कोड पोस्ट कर सकते हैं? वैकल्पिक रूप से, पुष्टि करें कि प्रत्येक कनेक्शन प्रत्येक पुनरावृत्ति के साथ स्थापित नहीं किया जा रहा है (बार-बार एक कनेक्शन का उपयोग करने के बजाय), और पुष्टि करें कि आप प्रत्येक पुनरावृत्ति के साथ 'conn.prepareCall() 'को कॉल नहीं कर रहे हैं (केवल' .setInt () 'और' .execute() 'लूप में)। – Matt

+1

आप अपनी संग्रहीत प्रक्रिया को एक से अधिक बार कॉल करते हैं, सही? क्या आपने बैच कॉल का उपयोग करने की कोशिश की है? http://docs.oracle.com/javase/1.3/docs/guide/jdbc/getstart/callablestatement.html देखें 7.1.3 –

+1

20 कॉल करने के बजाय, एक अनामित पीएल/एसक्यूएल ब्लॉक क्यों न करें (शुरू करें ... कॉल प्रो ... कॉल प्रो ...... अंत;) जो आपकी संग्रहीत प्रो 20 बार कॉल करता है और अज्ञात ब्लॉक के साथ डेटाबेस में एक कॉल करता है। – GriffeyDog

उत्तर

8

आपकी टिप्पणी से, आपने अपने लूप के अंदर तैयार किया है। तैयार बयान (और कॉल करने योग्य बयान) का एक लाभ यह है कि आप इसे एक बार तैयार कर सकते हैं, और उसके बाद पैरामीटर में दिए गए मानों को स्वैप कर सकते हैं; प्रत्येक बार कॉल तैयार होने पर ओवरहेड होता है, इसलिए यदि आप इसे अपने लूप के बाहर ला सकते हैं, तो आप पाएंगे कि रन टाइम कम हो गया है। आप पाते हैं कि ऑटोकॉमिट को बंद करने से भी मदद मिलती है, क्योंकि प्रत्येक प्रतिबद्धता के साथ ओवरहेड होता है।

conn.setAutoCommit(false); 
CallableStatement stmt = conn.prepareCall(sql); 
while(true) { 
    stmt.setInt(1, value); 
    stmt.execute(); 
} 
conn.commit(); 
conn.setAutoCommit(true); 

(conn.setAutoCommit(true) प्रतिबद्ध है, लेकिन मैं यह स्पष्ट स्पष्ट होना करने के लिए लगता है)।

+0

धन्यवाद मैट। मैं इसे बहुत बेहतर समझता हूं मुझे यकीन है कि यह मेरे ठीक करेगा मुद्दा। मैं इसे और सर्जीओ के सुझाव की कोशिश करूंगा। अपना समय और मदद की सराहना करें :) –

+0

हाय मैट - आपके और सर्जीओ द्वारा सुझाए गए दोनों दृष्टिकोणों की कोशिश की, लेकिन मेरे जावा कोड के माध्यम से यह अभी भी धीमा है। –

+0

अद्यतन: मुझे लगता है कि प्रक्रिया स्वयं ही बहुत धीमी है, जब मैंने सीधे अपने ऑरैक क्लाइंट का उपयोग करके प्रक्रिया तक पहुंचने का प्रयास किया - इसमें प्रत्येक नंबर के लिए लगभग 2 मिनट लगते हैं।यह दिन के अलग-अलग समय के दौरान अलग-अलग व्यवहार करता है और यह ऐसा कुछ है जिसे मुझे जांचने की आवश्यकता है। आपकी सभी मदद का धन्यवाद। –

1

क्या आप बैच का उपयोग करने पर विचार नहीं करना चाहिए?

conn.setAutoCommit(false); 
CallableStatement stmt = conn.prepareCall(sql); 
while(true) { 
    stmt.setInt(1, value); 
    stmt.addBatch(); 
} 
stmt.executeBatch() 
conn.commit(); 
संबंधित मुद्दे