2013-01-12 21 views
11

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

मेरी एसक्यूएल क्वेरी अपेक्षाकृत जटिल है, एक अद्वितीय मूल्य लौटाएं (इसलिए, समस्या इंस्टॉलेशन कक्षाओं के लिए आवश्यक समय से संबंधित नहीं है) और इसमें 'नाम पैरामीटर' प्रारूप के साथ कई पैरामीटर शामिल हैं। यह क्वेरी स्ट्रिंग में संग्रहीत है। उदाहरण के लिए,

String myNamedNativeQuery = "select count(*) from tables "+ 
          "where column1 = :nameParameter1 "+ 
          "and column2 = :nameParameter2"; 
          //actually my sentence is much more complex!! 

जब मैं TOAD पर वाक्य निष्पादित करता हूं तो इसे कुछ मिलीसेकंड में हल किया जाता है। लेकिन इस वाक्य का उपयोग हाइबरनेट

SQLQuery query = session.createSQLQuery("myNamedNativeQuery"); 

query.setParameter(nameParameter1, value1); 
query.setParameter(nameParameter2, value2); 

query.uniqueResult(); 

समान परिणाम प्राप्त करने के लिए कई सेकंड आवश्यक हैं।

मुझे एहसास हुआ कि मैंने सीधे मूल क्वेरी पर पैरामीटर को प्रतिस्थापित किया है और फिर मैं हाइबरनेट का उपयोग करके वाक्य को निष्पादित करता हूं, समय बहुत कम हो जाता है। यह ऐसा कुछ होगा:

String strQuery = session.getNamedQuery("myNamedNativeQuery").getQueryString(); 

myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter1", value1); 
myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter2", value2); 

SQLQuery query = session.createSQLQuery("myNamedNativeQuery"); 
query.uniqueResult(); 

कोई जानता है कि क्या हो रहा है ??

अग्रिम धन्यवाद।

पुनश्च: Oracle संस्करण 9i और हाइबरनेट है 3.2

+1

हाइबरनेट के साथ "शो एसक्यूएल" विकल्प की बारी देखें। यह आपको यह प्रश्न दिखाएगा कि हाइबरनेट चल रहा है और आपको अंतर्दृष्टि देगा कि यह इतना समय क्यों ले रहा है। –

उत्तर

6

मुझे लगता है कि इस कोड के साथ हो रहा है:

लाइन 1 पर: एक प्रश्न योजना बनाई गई है आधारित

SQLQuery query = session.createSQLQuery("myNamedNativeQuery"); 
query.setParameter(nameParameter1, value1); 
query.setParameter(nameParameter2, value2); 
query.uniqueResult(); 

यह है आपके नामित पैरामीटर के लिए कुछ अपेक्षित मूल्यों पर।

लाइन 4 पर: क्वेरी को मान 1 और मान 2 के साथ निष्पादित किया गया है, लेकिन वे मान क्वेरी योजना के लिए "अच्छे मूल्य" नहीं हैं जो लाइन 1 पर विस्तृत थे और इसलिए, डेटाबेस वास्तविक के लिए एक बहुत ही अनुचित योजना निष्पादित कर रहा है मूल्य और इसमें बहुत समय लगता है।

क्यों?

SQLQueryImpl query = new SQLQueryImpl(
       sql, 
         this, 
         factory.getQueryPlanCache().getSQLParameterMetadata(sql) 
     ); 

जो कुछ parameterMetaData साथ getQueryPlanCache() बुला रहा है:

HibernateSessionImpl.createSQLQuery(...) के स्रोत कोड को देखते हुए मैं कोड की इस पंक्ति पाया। मुझे लगता है कि यह मेटाडाटा पर्याप्त नहीं है।

+0

दिलचस्प ... तो, इन मामलों में सबसे अच्छा अभ्यास क्या होगा ?? शायद createSQLQuery() को कॉल करने से पहले पैरामीटर को उनके मानों के साथ बदलना? – Sobrino

+0

शायद अनुकूली कर्सर साझा करने में मदद मिलेगी। लेकिन यह सुविधा 11 जी तक उपलब्ध नहीं है। –

+0

मेरे परीक्षणों के मुताबिक, यह स्थिति session.getNamedQuery ('myNamedQuery') का उपयोग करके होती है। ऐसा लगता है कि हाइबरनेट क्वेरी योजनाओं को कैश कर रहा है और कुछ पैरामीटर के साथ चुनी गई क्वेरी प्लान सबसे अच्छी नहीं है। तो, क्वेरी प्लान कैश को कॉन्फ़िगर करना संभव होगा? – Sobrino

0

आप के लिए मेरा जवाब है:

निकालें सब बाँध मापदंड और मान

StatelessSession session = sessionFactory.openStatelessSession(); 

मैं इसी तरह की समस्या थी पैरामीटर सहित पूरा एसक्यूएल साथ StatelessSession का उपयोग सत्र

उपयोग SQLQuery के बजाय खोज क्वेरी के बजाय और जब तक मुझे बेहतर समाधान नहीं मिलता है, वैसे ही मैं इसे काम करने में कामयाब रहा हूं। Hibernate parameterized sql query slow and active oracle sessions