एक सहयोगी ने मुझे यह बताने के लिए कहा कि इंडेक्स (इंडेक्स?) प्रदर्शन को कैसे बढ़ाता है; मैंने ऐसा करने की कोशिश की, लेकिन खुद को भ्रमित कर दिया।
मैंने स्पष्टीकरण के लिए नीचे दिए गए मॉडल का उपयोग किया (एक त्रुटि/डायग्नोस्टिक लॉगिंग डेटाबेस)। यह तीन तालिकाओं के होते हैं:कंपाउंड इंडेक्स में जॉइन-एड क्वेरी को तेज़ करने की आवश्यकता है?
- व्यापार प्रणालियों की सूची, टेबल "सिस्टम" से युक्त उनके नाम
- निशान, टेबल "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 सिंगल-कॉलम इंडेक्स का उपयोग करने के लिए बहुत बड़ा बनाता है। लेकिन क्या यह सच है?
tahnk आप, मुझे इस तरह के "एक सूचकांक प्रति तालिका" नियम के बारे में कभी नहीं पता था, लेकिन यह मेरी समस्या को समझाने के लिए तार्किक और भी प्रतीत होता है (मैं mysql5.4.something में था)। – naivists