यह मुख्य जनसंख्या (टुपल कार्डिनैलिटी) पर आधारित 5% नियम के कारण है।
यदि आप एक ऐसी तालिका को अनुक्रमित करते हैं जहां एकतरफा कार्डिनैलिटी मौजूद है, तो MySQL क्वेरी ऑप्टिमाइज़र हमेशा कम से कम प्रतिरोध का रास्ता चुनेगा।
उदाहरण:यदि किसी तालिका में लिंग स्तंभ है, तो कार्डिनैलिटी दो है, M और F.
आप इस तरह के लिंग कॉलम को क्या इंडेक्स कर रहे हैं ??? आपको अनिवार्य रूप से दो विशाल लिंक्ड सूचियां मिलती हैं।
यदि आप लिंग स्तंभ वाली तालिका में दस लाख पंक्तियों को लोड करते हैं, तो आपको 50% M और 50% F मिल सकता है।
क्वेरी ऑप्टिमाइज़ेशन के दौरान एक इंडेक्स बेकार हो जाता है यदि एक प्रमुख कॉम्बो (प्रमुख जनसंख्या जैसा कि मैंने इसे वाक्यांशित किया है) की कार्डिनैलिटी कुल तालिका गणना के 5% से अधिक है।
अब, आपके उदाहरण के संबंध में, दो अलग-अलग EXPLAIN योजनाएँ क्यों ??? मेरा अनुमान है कि एक टैग टीम के रूप में MySQL क्वेरी ऑप्टिमाइज़र और InnoDB है।
पहले CREATE TABLE में, टेबल और इंडेक्स एक ही आकार के होते हैं, हालांकि छोटे होते हैं, इसलिए ने इंडेक्स स्कैन करके फुल टेबल स्कैन नहीं करके इंडेक्स के पक्ष में फैसला किया . ध्यान रखें कि गैर-अद्वितीय अनुक्रमणिका अपनी अनुक्रमणिका प्रविष्टियों में प्रत्येक पंक्ति की आंतरिक प्राथमिक कुंजी (RowID) को चारों ओर ले जाती है, इस प्रकार अनुक्रमणिका को लगभग तालिका के समान आकार का बना देती है।
दूसरे क्रिएट टेबल में, एक अन्य कॉलम, उपयोगकर्ता की शुरूआत के कारण, अब आप क्वेरी ऑप्टिमाइज़र को एक पूरी तरह से अलग परिदृश्य देखते हैं:तालिका अब इंडेक्स से बड़ी हो गई है . इसलिए, उपलब्ध इंडेक्स का उपयोग करने के तरीके की व्याख्या में क्वेरी ऑप्टिमाइज़र अधिक सख्त हो गया। यह उस 5% नियम पर चला गया जिसका मैंने पहले उल्लेख किया था। वह नियम बुरी तरह विफल रहा और क्वेरी ऑप्टिमाइज़र ने एक पूर्ण तालिका स्कैन के पक्ष में निर्णय लिया।