2012-01-04 15 views
5

का उपयोग नहीं करती है, मैं अपने आवेदन के प्रदर्शन मुद्दे को हल करने का प्रयास करता हूं। क्वेरी हाइबरनेट उत्पन्न करता है, फार्म की है:हाइबरनेट ऐप से क्वेरी डीबी इंडेक्स

select * 
from ( 
    select this.a, this.b, this.state, this.id 
    from view_user this 
    where this.state=:1 order by this.a asc, this.b 
) 
where rownum <= :2 

जहां

  • आईडी है प्राथमिक कुंजी
  • है पर एक संयुक्त, अद्वितीय सूचकांक (ए, बी, आईडी)।
  • view_user ~ 2 लाख प्रविष्टियां हैं
  • view_user करता है कुछ और अन्य तालिकाओं

अंक

ऊपर क्वेरी प्रदर्शन करने के लिए मिलती है - तेजी से SQLDeveloper से - जल्दी एक छोटी सी जावा app से हाइबरनेट - हाइबरनेट के साथ एप्लिकेशन से बेहद धीमी (> 100x धीमी) - बाध्य चर के लिए मान 2 क्रमशः 30 (पेजिंग से राउनम उत्पत्ति) - हाइबरनेट क्वेरी उपरोक्त फॉर्म "है। वास्तव में दृश्य में लगभग 20 कॉलम हैं।

विश्लेषण के वर्तमान राज्य

  • क्वेरी योजना पता चलता है कि सूचकांक जब क्वेरी SQlDeveloper या "छोटे जावा एप्लिकेशन" से आता है प्रयोग किया जाता है।
  • क्वेरी योजना से पता चलता है कि पूरा तालिका स्कैन प्रदर्शन कर रहे हैं, बशर्ते क्वेरी
  • डीबी ट्रेसिंग केवल दो मतभेदों को दर्शाता है हाइबरनेट एप्लिकेशन से आता है: (SQLDeveloper से) NLS सेटिंग्स और थोड़ा अलग स्वरूपण (व्हाइटस्पेस)। 2.1.8
  • JDBC ड्राइवर: इस्तेमाल किया ojdbc14, 5 और 6 में कोई अंतर नहीं बनाता
  • ओरेकल बाकी सब कुछ एक ही हो ...

संस्करण

  • हाइबरनेट लगता है : 10.2 और 11. कोई फर्क नहीं पड़ता

=> मुझे इस मुद्दे से संबंधित हर संकेत के बारे में खुशी है। मुझे क्या परेशानियां यह तथ्य है कि डीबी ट्रेसिंग ने कोई अंतर नहीं दिखाया ... हाँ, ऐसा लगता है कि यह हाइबरनेट के बारे में कुछ है। पर क्या? कैसे पता लगाया जाए?


पूर्णता के लिए, यहाँ (लॉग से) हाइबरनेट क्वेरी के लिए:

Select * from ( 
    select this.USER_ID as USER_ID0_, this.CLIENT_ID as CLIENT_ID0_, 
    this.USER_NAME as USER_NAME0_, this.USER_FIRST_NAME as USER_FIR5_0_, this.USER_REMARKS as 
    USER_REM6_0_, this.USER_LOGIN_ID as USER_LOG7_0_, this.USER_TITLE as USER_TITLE0_, 
    this.user_language_code as user_lan9_0_, this.USER_SEX as USER_SEX0_, 
    this.USER_BIRTH_DATE as USER_BI11_0_, this.USER_TELEPHONE as USER_TE12_0_, 
    this.USER_TELEFAX as USER_TE13_0_, this.USER_MOBILE as USER_MO14_0_, 
    this.USER_EMAIL as USER_EMAIL0_, this.USER_ADDRESSLINE1 as USER_AD16_0_, 
    this.USER_ADDRESSLINE2 as USER_AD17_0_, this.USER_POSTALCODE as USER_PO18_0_, 
    this.USER_CITY as USER_CITY0_, this.USER_COUNTRY_CD as USER_CO20_0_, 
    this.USER_COUNTRY_NAME as USER_CO21_0_, this.USER_STATE_ID as USER_ST24_0_, 
    this.USER_STATE as USER_STATE0_, this.USER_TEMP_COLL_ID as USER_TE26_0_, 
    this.USER_TEMP_COLL_NAME as USER_TE27_0_, this.UNIT_ID as UNIT_ID0_, 
    this.CLIENT_NAME as CLIENT_38_0_, this.PROFILE_EXTID as PROFILE39_0_ 
    from VIEW_USER this 
    where this.USER_STATE_ID=:1 order by this.USER_NAME asc, this.USER_FIRST_NAME asc 
) 
where rownum <= :2 

अनोखा सूचकांक user_name, USER_FIRST_NAME, user_id खत्म हो गया है।

+0

मुझे संदेह है कि आपके पास अपनी क्वेरी में एक टाइपो है जिसे आपने यहां दर्ज किया है, क्योंकि आंतरिक चयन में दो 'कहां है। क्या वास्तव में बाहरी चयन पर 'जहां रोउनम' खंड है? – rejj

+1

आप कहते हैं कि "view_user में ~ 2 mio प्रविष्टियां हैं"। कृपया "एमओओ" परिभाषित करें। साथ ही, view_user.state के संभावित मान क्या हैं, और प्रत्येक संभावित मूल्य के लिए कितनी पंक्तियां हैं? आखिरकार, 1 और 2 के लिए कौन से मूल्य प्रदान किए जा रहे हैं? धन्यवाद। –

+0

सूखी, एमओओ लाख है। आंतरिक चयन का पूरा रिटर्न सेट पूर्ण दृश्य (view_user) का लगभग 80% हो सकता है क्योंकि "this.state =: 1" के लिए मान 2 के साथ: 1। –

उत्तर

1

आपके द्वारा दिया गया एसक्यूएल हाइबरनेट उत्पन्न क्वेरी की तरह नहीं दिखता है। क्या आप वाकई हस्तलिखित प्रश्न नहीं हैं?

यदि आप हाइबरनेट का उपयोग करना चाहते हैं तो आप पंक्तियों की संख्या को सीमित करने के लिए setMaxResults() का उपयोग कर सकते हैं।

आप एक हस्तलिखित क्वेरी मैं आपको लगता है उपयोग करना चाहते हैं चाहते हैं कुछ इस तरह:

select * 
( से

this.a का चयन करें, this.b, this.state, इस view_user से this.id जहां this.state =: 1 क्रम this.a एएससी द्वारा, this.b ) जहां ROWNUM < =: डीबगिंग और चारों ओर की कोशिश कर के एक बहुत बाद 2

+0

टाइपो के लिए सूखी है। क्वेरी को सरल बनाया गया है, लेकिन अभी भी वही तर्कसंगत है। चयन में कॉलम सूची के कारण हाइबरनेट थोड़ा अधिक जटिल दिखता है। –

+0

एनपी। क्या VIEW_USER.USER_STATE_ID पर कोई अनुक्रमणिका है? –

+0

हाँ, वहाँ है। state_id एक तालिका के लिए एक विदेशी कुंजी है जहां state_id प्राथमिक कुंजी है। –

0

, मैं एक जवाब है इस समस्या को ठीक करने के लिए। हालांकि, मैं अभी तक समझा नहीं सकता कि समस्या वास्तव में क्या है।

यह मुद्दा जेडीबीसी कनेक्शन पूलिंग स्तर पर प्रतीत होता है। मेरे config था:

  • initialSize = 0
  • minIdle = 10

ऊपर विन्यास का उपयोग करना, हम लक्षण मुद्दा descritpion में वर्णित के रूप था। ऐसा लगता है कि समाधान अब तक प्रारंभिक आकार के बराबर minIdle सेट करना प्रतीत होता है। अन्यथा, कनेक्शन किसी भी तरह से शुरू किया जा रहा प्रतीत होता है और हम प्रदर्शन में कमी देखते हैं। तो, हम दोनों '10' पर सेट करते हैं।

मैं वर्तमान में लॉग का विश्लेषण कर रहा हूं। डीबी सर्वर पर, ट्रेस फाइलें कोई अंतर नहीं दिखाती हैं। जेडीबीसी ट्रेसिंग ने अभी तक कोई रोचक जानकारी नहीं दिखाई है।

गुगलिंग, मैंने देखा कि बहुत सारे नमूना विन्यास minIdle = प्रारंभिक आकार सेट करें। इसके अलावा मुझे जेडीबीसी सेटिंग्स से संबंधित दो उद्धरण (वसंत डॉकू, वीएमवेयर डॉकू) मिला:

मिनीइडल: पूल में रखे गए स्थापित कनेक्शन की न्यूनतम संख्या हर समय पूल में रखी जानी चाहिए। सत्यापन प्रश्न विफल होने पर कनेक्शन पूल इस नंबर से नीचे हट सकता है। डिफ़ॉल्ट मान प्रारंभिक आकार से लिया गया है।

ध्यान दें कि "प्रारंभिक आकार से व्युत्पन्न अंतिम वाक्य" मिनीडिल्ड के लिए सभी दस्तावेजों में नहीं मिला है। अधिकांश दस्तावेज डिफ़ॉल्ट रूप से '0' का उल्लेख करते हैं।

+0

ठीक है, काम-आसपास नॉक है। शुरुआत में शुरू होने वाले सभी कनेक्शन (प्रारंभिक आकार के कारण) ठीक हैं और परिणामस्वरूप तेज प्रश्न होंगे, यानी, सही क्वेरी योजना ली जाती है। लेकिन जैसे ही एक नया कनेक्शन बनाया जाता है क्योंकि स्टार्टअप पर पर्याप्त रूप से नहीं बनाया गया था, उन नव निर्मित कनेक्शनों में प्रदर्शन समस्या होगी। –

1

इस मुद्दे का अंतिम समाधान c3p0 था। हम ट्रैक करने में सक्षम नहीं थे कि गलत क्वेरी योजना क्यों चुनी गई थी। हमारी अंतिम धारणा यह है कि डीबीसीपी के कनेक्शन प्रारंभिकरण के साथ इसका कुछ संबंध है। लेकिन समय की झील के कारण, हमने c3p0 को आजमाया। पहले के अनुभवों:

  • मुद्दा
  • तेजी पूल
  • के लिए कॉन्फ़िगर MaxConnections का उपयोग कर के मामले में और ऊपर बिंदु की वजह से क्योंकि बहुत ज्यादा आक्रामक प्रकट नहीं होता है, हमारे पूर्ण आवेदन अब तेजी से होता है। यह जब हमारे विभिन्न भार के साथ-साथ अनुप्रयोग का उपयोग सामान्य धारणा के आधार पर

तो परीक्षण है, इस समय हम बेसब्री से बाहर विभिन्न परिदृश्यों c3p0 साथ क्रम में परीक्षण कर रहे हैं उत्पादक प्रणालियों के लिए तैयार होने के लिए।

सभी इनपुट के लिए धन्यवाद!

4

मैं एक समान स्थिति में आया हूं, इसलिए यह आपके लिए प्रासंगिक हो सकता है।

जेडीबीसी ड्राइवर आपके मानकों को यूनिकोड में बदल रहा है, इसलिए varchar डेटाबेस पर हिट होने पर nvarchar बन जाता है। यदि आप भाग्यशाली एसक्यूएल 2008 एसपी 1 इसे पकड़ लेंगे और इसे वापस परिवर्तित करेंगे। लेकिन एसक्यूएल 2000 और एसक्यूएल 2005 नहीं होगा और क्वेरी ऑप्टिमाइज़र आपके इंडेक्स को अनदेखा कर एक पूर्ण टेबल स्कैन करेगा।

आप अपने कनेक्शन स्ट्रिंग में कनेक्शन पैरामीटर sendStringParametersAsUnicode=FALSE जोड़कर जेडीबीसी परत पर इसे ठीक करने में सक्षम हो सकते हैं।

+0

धन्यवाद इसने एक इलाज किया। मैं हाइबरनेट 4.2.16 और SQL सर्वर 2008 SP4 और sqlJdbc4 माइक्रोसॉफ्ट ड्राइवरों का उपयोग कर रहा हूं। एक ही मुद्दा था जहां मैं एक एसक्यूएल क्लाइंट पर एक ही क्वेरी कर रहा था और यह तुरंत वापस आ जाएगा और जावा + हाइबरनेट के माध्यम से इसमें 4-5 सेकंड लगेंगे। ऊपर जोड़ा गया और बीएएम :) – kohlerfc

0

वहाँ एक जवाब से ऊपर/नीचे एसक्यूएल सर्वर के लिए सेटिंग के साथ nvarchars के बारे में है - यहाँ ओरेकल के लिए एक समान सेटिंग है ...

चेक oracle.jdbc.defaultNChar = सच बनाने के लिए यकीन है कि कोई गुण सेट नहीं किया है

यह कभी-कभी यूनिकोड समस्याओं को हल करने के लिए किया जाता है लेकिन इसका मतलब है कि सभी स्तंभों को nvarchars के रूप में माना जाता है। यदि आपके पास वर्चर कॉलम पर एक इंडेक्स है, तो इसका उपयोग नहीं किया जाएगा क्योंकि ऑरैकल को अक्षर एन्कोडिंग को परिवर्तित करने के लिए फ़ंक्शन का उपयोग करना होगा।

-1

हमें एक ही समस्या थी: SQL डेवलपर से क्वेरी चलाते समय, समझाया गया योजना दिखाती है कि इंडेक्स का उपयोग किया गया था, लेकिन जब हाइबरनेट के माध्यम से एप्लिकेशन में क्वेरी चलाते समय, इंडेक्स को अनदेखा कर दिया गया था।

हमने क्वेरी में इंडेक्स का उपयोग करने के लिए ओरेकल ऑप्टिमाइज़र को क्वेरी में एक संकेत जोड़कर हल किया।

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