2010-01-12 7 views
6

एक सहयोगी ने मुझे यह बताने के लिए कहा कि इंडेक्स (इंडेक्स?) प्रदर्शन को कैसे बढ़ाता है; मैंने ऐसा करने की कोशिश की, लेकिन खुद को भ्रमित कर दिया।
मैंने स्पष्टीकरण के लिए नीचे दिए गए मॉडल का उपयोग किया (एक त्रुटि/डायग्नोस्टिक लॉगिंग डेटाबेस)। यह तीन तालिकाओं के होते हैं:कंपाउंड इंडेक्स में जॉइन-एड क्वेरी को तेज़ करने की आवश्यकता है?

  • व्यापार प्रणालियों की सूची, टेबल "सिस्टम" से युक्त उनके नाम
  • निशान, टेबल "TraceTypes" के विभिन्न प्रकार की सूची, को परिभाषित त्रुटि संदेशों में से किस प्रकार लॉग इन किया जा सकता है
  • वास्तविक ट्रेस संदेश, System और TraceTypes टेबल

मैं डेमो के लिए MySQL का इस्तेमाल किया से विदेशी कुंजी है, लेकिन मैं तालिका प्रकार मैं इस्तेमाल किया याद नहीं है। मुझे लगता है कि यह InnoDB था।

System        TraceTypes 
-----------------------------   ------------------------------------------ 
| ID   | Name  |   | ID | Code | Description   | 
-----------------------------   ------------------------------------------ 
| 1   | billing  |   | 1  | Info | Informational mesage | 
| 2   | hr   |   | 2  | Warning| Warning only   | 
-----------------------------   | 3  | Error | Failure    | 
      |       ------------------------------------------ 
      |    ------------| 
Traces |    |    
-------------------------------------------------- 
| ID | System_ID | TraceTypes_ID | Message  | 
-------------------------------------------------- 
| 1 | 1  | 1   | Job starting | 
| 2 | 1  | 3   | System.nullr..| 
-------------------------------------------------- 

सबसे पहले, मैं टेबल के सभी के लिए कुछ रिकॉर्ड जोड़े और दिखा दिया कि क्वेरी के नीचे 0.005 सेकंड में कार्यान्वित:

select count(*) from Traces 
    inner join System on Traces.System_ID = System.ID 
    inner join TraceTypes on Traces.TraceTypes_ID = TraceTypes.ID 
where 
    System.Name='billing' and TraceTypes.Code = 'Info' 

तो मैं और अधिक डेटा उत्पन्न (कोई अनुक्रमणिका अभी तक)

  • "सिस्टम" में लगभग 100 प्रविष्टियां
  • "ट्रेसटाइप" में लगभग 50 प्रविष्टियां हैं
  • "निशान" में ~ 10 मिलियन रिकॉर्ड शामिल थे।

अब पिछली क्वेरी में 8-10 सेकंड लग गए थे।

मैंने Traces.System_ID कॉलम और Traces.TraceTypes_ID कॉलम पर इंडेक्स बनाए। अब इस क्वेरी मिलीसेकेंड में मार डाला:

select count(*) from Traces where System_id=1 and TraceTypes_ID=1; 

यह भी तेजी से किया गया था:

select count(*) from Traces 
    inner join System on Traces.System_ID = System.ID 
where System.Name='billing' and TraceTypes_ID=1; 

लेकिन पिछली क्वेरी जो सभी तीन तालिकाओं में शामिल हो गए अभी भी पूरा करने के लिए 8-10 सेकंड लिया।

केवल तभी जब मैंने एक कंपाउंड इंडेक्स बनाया (इंडेक्स में सिस्टम_आईडी और ट्रेसटाइप_आईडी कॉलम दोनों शामिल थे), तो गति मिलीसेकंड तक गिर गई।

मुझे जो बुनियादी वक्तव्य पहले सिखाया गया था वह है "आप जिन सभी स्तंभों में शामिल होने के लिए उपयोग करते हैं, उन्हें अनुक्रमित किया जाना चाहिए"।
हालांकि, मेरे परिदृश्य में मेरे पास System_ID और TraceTypes_ID दोनों पर इंडेक्स था, हालांकि MySQL ने उनका उपयोग नहीं किया था। सवाल यह है - क्यों? मेरा दांव है - आइटम गणना अनुपात 100: 10,000,000: 50 सिंगल-कॉलम इंडेक्स का उपयोग करने के लिए बहुत बड़ा बनाता है। लेकिन क्या यह सच है?

उत्तर

2

धीमे एसक्यूएल कथन का विश्लेषण करने के लिए सबसे पहले, सही, और सबसे आसान तरीका एक्सप्लाइन करना है। पता लगाएं कि ऑप्टिमाइज़र ने अपनी योजना कैसे चुना और इस पर विचार करें कि इसे क्यों और कैसे सुधारें। मैं अपने कथन को निष्पादित करने के तरीके को देखने के लिए केवल 2 अलग-अलग इंडेक्स के साथ EXPLAIN परिणामों का अध्ययन करने का सुझाव दूंगा।

मैं MySQL से बहुत परिचित नहीं हूं, लेकिन ऐसा लगता है कि एक प्रश्न में शामिल प्रति तालिका केवल एक अनुक्रमणिका का उपयोग करने के MySQL 4 का प्रतिबंध है। MySQL 5 (index merge) के बाद से इसमें सुधार होने लगते हैं, लेकिन मुझे यकीन नहीं है कि यह आपके मामले पर लागू होता है या नहीं। फिर, एक्सप्लाइन आपको सच बताएगा।

2 अलग-अलग इंडेक्स का उपयोग करके 2 अलग इंडेक्स प्रति तालिका (MySQL 5) का उपयोग करने के साथ भी आमतौर पर यौगिक सूचकांक की तुलना में धीमी है। एक कंपाउंड इंडेक्स का उपयोग करने के एकल पास की तुलना में 2 अलग-अलग इंडेक्स का उपयोग करके इंडेक्स विलय चरण की आवश्यकता होती है।

Multi Column indexes vs Index Merge सहायक हो सकता है, जो MySQL 5.4.2 का उपयोग करता है।

+0

tahnk आप, मुझे इस तरह के "एक सूचकांक प्रति तालिका" नियम के बारे में कभी नहीं पता था, लेकिन यह मेरी समस्या को समझाने के लिए तार्किक और भी प्रतीत होता है (मैं mysql5.4.something में था)। – naivists

0

मेरा अनुमान है कि यह सूचकांक का उपयोग करेगा और फिर यह किसी अन्य इंडेक्स में जाने के लिए पारंपरिक रूप से उपयोग कर रहा है और फिर फ़िल्टर कर सकता है। कृपया निष्पादन योजना की जांच करें। तो संक्षेप में आप नेस्टेड पाश में दो इंडेक्स के माध्यम से लूपिंग हो सकता है। मेरी समझ के अनुसार। हमें कॉलम पर एक समग्र इंडेक्स बनाने की कोशिश करनी चाहिए जो फ़िल्टरिंग में है या इसमें शामिल है और फिर हमें कॉलम के लिए क्लॉज शामिल करना चाहिए जो चुनिंदा हैं। मैंने कभी MySQL में काम नहीं किया है, इसलिए मेरी यह समझ SQL सर्वर 2005 पर आधारित है।

1

यह इंडेक्स का आकार इतना नहीं है कि चयनकर्ता यह निर्धारित करता है कि ऑप्टिमाइज़र उनका उपयोग करेगा या नहीं।

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