आमतौर पर कौन से कॉलम अच्छे इंडेक्स बनाते हैं?


98

" अनुक्रमणिका क्या हैं और मैं उन्हें अपने डेटाबेस में प्रश्नों को अनुकूलित करने के लिए कैसे उपयोग कर सकता हूं? " के रूप में अनुक्रमणिका के बारे में जानने का प्रयास कर रहा हूं कि अच्छे सूचकांक वाले कौन से कॉलम हैं? विशेष रूप से एक MS SQL डेटाबेस के लिए?

कुछ गुगली करने के बाद, मैंने जो कुछ भी पढ़ा है वह बताता है कि आम तौर पर बढ़ रहे स्तंभ और अद्वितीय एक अच्छा सूचकांक बनाते हैं (MySQL के auto_increment जैसी चीजें), मैं इसे समझता हूं, लेकिन मैं एमएस SQL ​​का उपयोग कर रहा हूं और प्राथमिक कुंजी के लिए GUID का उपयोग कर रहा हूं, इसलिए ऐसा लगता है कि अनुक्रमणिका GUID स्तंभों को लाभान्वित नहीं करेगी ...


"रसोई की किताब" के बारे में कैसे: mysql.rjweb.org/doc.php/index_cookbook_mysql
रिक जेम्स

जवाबों:


110

इंडेक्स क्वेरी ऑप्टिमाइज़ेशन और तालिकाओं से तेज़ी से परिणाम खोजने में महत्वपूर्ण भूमिका निभा सकते हैं। तो यह सबसे महत्वपूर्ण कदम है कि किन कॉलमों को अनुक्रमित किया जाए। दो प्रमुख स्थान हैं जहाँ हम अनुक्रमण पर विचार कर सकते हैं: WHERE क्लॉज़ में संदर्भित कॉलम और JOIN क्लॉज़ में प्रयुक्त कॉलम। संक्षेप में, ऐसे स्तंभों को अनुक्रमित किया जाना चाहिए जिनके खिलाफ आपको विशेष रिकॉर्ड खोजने की आवश्यकता होती है। मान लीजिए, हमारे पास खरीदारों की एक तालिका है, जहां SELECT क्वेरी नीचे की तरह अनुक्रमित का उपयोग करती है:

SELECT
 buyer_id /* no need to index */
FROM buyers
WHERE first_name='Tariq' /* consider to use index */
AND last_name='Iqbal'   /* consider to use index */

चूंकि "क्रेता_ड" को SELECT हिस्से में संदर्भित किया गया है, इसलिए MySQL इसे चुने हुए पंक्तियों को सीमित करने के लिए उपयोग नहीं करेगा। इसलिए, इसे इंडेक्स करने की कोई बड़ी जरूरत नहीं है। नीचे एक और उदाहरण है जो ऊपर वाले से थोड़ा अलग है:

SELECT
 buyers.buyer_id, /* no need to index */
 country.name    /* no need to index */
FROM buyers LEFT JOIN country
ON buyers.country_id=country.country_id /* consider to use index */
WHERE
 first_name='Tariq' /* consider to use index */
AND
 last_name='Iqbal' /* consider to use index */

उपरोक्त प्रश्नों के अनुसार first_name, last_name स्तंभों को अनुक्रमित किया जा सकता है क्योंकि वे WHERE क्लॉज में स्थित हैं। इसके अलावा, एक अतिरिक्त फ़ील्ड, कंट्री टेबल से कंट्री_ड को इंडेक्सिंग के लिए माना जा सकता है क्योंकि यह एक जॉइन क्लॉज में है। इसलिए हर क्षेत्र में WHRE क्लॉज़ या JOIN क्लॉज़ में अनुक्रमण को माना जा सकता है।

निम्नलिखित सूची में कुछ सुझाव भी दिए गए हैं जिन्हें आपको हमेशा ध्यान में रखना चाहिए जब आप अपनी तालिका में अनुक्रमित बनाने का इरादा रखते हैं:

  • केवल उन कॉलमों को अनुक्रमित करें जो WHERE और ORDER BY क्लॉस में आवश्यक हैं। बहुतायत में अनुक्रमण स्तंभों के परिणामस्वरूप कुछ नुकसान होंगे।
  • MySQL के "इंडेक्स प्रीफिक्स" या "मल्टी-कॉलम इंडेक्स" फीचर का लाभ उठाने की कोशिश करें। यदि आप INDEX (first_name, last_name) जैसे इंडेक्स बनाते हैं, तो INDEX (first_name) न बनाएं। हालांकि, सभी खोज मामलों में "इंडेक्स प्रीफिक्स" या "मल्टी-कॉलम इंडेक्स" की सिफारिश नहीं की जाती है।
  • उन स्तंभों के लिए NOT NULL विशेषता का उपयोग करें जिनमें आप अनुक्रमण पर विचार करते हैं, ताकि NULL मान कभी संग्रहीत न हों।
  • अनुक्रमणिका का उपयोग न करने वाले प्रश्नों को लॉग करने के लिए --log-long-format विकल्प का उपयोग करें। इस तरह, आप इस लॉग फ़ाइल की जांच कर सकते हैं और अपने प्रश्नों को तदनुसार समायोजित कर सकते हैं।
  • EXPLAIN स्टेटमेंट आपको यह बताने में मदद करता है कि MySQL क्वेरी को कैसे निष्पादित करेगा। यह दिखाता है कि टेबल कैसे और किस क्रम में जुड़ती है। यह निर्धारित करने के लिए बहुत उपयोगी हो सकता है कि अनुकूलित प्रश्नों को कैसे लिखा जाए, और क्या स्तंभों को अनुक्रमित करने की आवश्यकता है।

अपडेट (23 फरवरी 15):

कोई भी इंडेक्स (अच्छा / खराब) इन्सर्ट और अपडेट टाइम बढ़ाता है।

आपके अनुक्रमित (अनुक्रमित और प्रकार की संख्या) के आधार पर, परिणाम खोजा जाता है। यदि आपकी खोज का समय सूचकांक के कारण बढ़ने वाला है तो यह खराब सूचकांक है।

किसी भी किताब में, "इंडेक्स पेज" में चैप्टर स्टार्ट पेज, टॉपिक पेज नंबर शुरू, सब सब्जेक्ट पेज भी शुरू हो सकता है। सूचकांक पृष्ठ में कुछ स्पष्टीकरण मदद करता है लेकिन अधिक विस्तृत सूचकांक आपको भ्रमित कर सकता है या आपको डरा सकता है। इंडेक्स में भी मेमोरी होती है।

सूचकांक चयन बुद्धिमान होना चाहिए। ध्यान रखें कि सभी स्तंभों को सूचकांक की आवश्यकता नहीं होगी।


धन्यवाद सोमनाथ, तो क्या इसका मतलब है कि अनुक्रमणिका केवल उन स्तंभों के लिए बनाई जानी चाहिए जहां हम उपयोग करने की योजना बना रहे हैं WHERE, JOINSया HAVING?
मुहम्मद बाबर

3
हां, उन स्तंभों के लिए अनुक्रमणिका का उपयोग करें जहां आप WHERE, JOINS या HAVING का उपयोग करने की योजना बना रहे हैं। लेकिन यह भी ध्यान रखें, सभी शर्त स्तंभों को अनुक्रमित की आवश्यकता नहीं है। कभी-कभी जहां हालत स्तंभ केवल एक बार उपयोग किया जाता है, इसलिए उसे सूचकांक की आवश्यकता नहीं हो सकती है जबकि अन्य स्थिति कॉलम का उपयोग कई प्रश्नों में किया जाता है, इसलिए उस कॉलम को अनुक्रमित करने के लिए अधिक पसंद करें।
सोमनाथ मुलुक

1
उत्तर देने से फायदा होगा, "टीआर? डीआर सेक्शन में WHERE क्लॉज और JOIN क्लॉस में इस्तेमाल किए गए कॉलम" में संदर्भित कॉलम।
jpmc26

तो आप कह रहे हैं कि यदि मेरे WHEREखंड में मैं एक ऐसे क्षेत्र का मान जाँच रहा हूँ जहाँ उसका स्तंभ केवल दो मान ले सकता है, तो मुझे उस बाइनरी कॉलम को इंडेक्स करना चाहिए? यह गलत लगता है।
AjaxLeung

@AjaxLeung: याद रखें कि नुथ की अधिकतम "समयपूर्व अनुकूलन सभी बुराई की जड़ है।" आप बाइनरी कॉलम पर इंडेक्स बना सकते हैं, लेकिन यह किस कीमत (जैसे इन्सर्ट, अपडेट टाइम) पर निर्भर होना चाहिए। यदि आपका व्यावसायिक तर्क अक्सर उस बाइनरी स्विच पर निर्भर करता है तो बाइनरी कॉलम को इंडेक्स की आवश्यकता हो सकती है।
सोमनाथ मुलुक

20

कुछ लोगों ने यहां एक समान सवाल का जवाब दिया: आप कैसे जानते हैं कि एक अच्छा सूचकांक क्या है?

असल में, यह वास्तव में इस बात पर निर्भर करता है कि आप अपने डेटा की क्वेरी कैसे करेंगे। आप एक ऐसा सूचकांक चाहते हैं जो आपके डेटासेट के एक छोटे उपसमूह की पहचान करता है जो एक क्वेरी के लिए प्रासंगिक है। यदि आप डेटास्टैम्प द्वारा कभी क्वेरी नहीं करते हैं, तो आपको इस पर एक इंडेक्स की आवश्यकता नहीं है, भले ही यह ज्यादातर अद्वितीय हो। यदि आप सभी करते हैं तो एक निश्चित तिथि सीमा में होने वाली घटनाएं होती हैं, तो आप निश्चित रूप से एक चाहते हैं। ज्यादातर मामलों में, लिंग पर एक सूचकांक व्यर्थ है - लेकिन अगर आप सभी करते हैं, तो सभी पुरुषों के बारे में आँकड़े प्राप्त होते हैं, और अलग-अलग, सभी महिलाओं के बारे में, यह एक बनाने के लिए आपके लायक हो सकता है। पता लगाएँ कि आपके क्वेरी पैटर्न क्या होंगे, और किस पैरामीटर तक पहुंच खोज स्थान को सबसे अधिक बताती है, और यह आपका सबसे अच्छा सूचकांक है।

इस बात पर भी विचार करें कि आप किस तरह का इंडेक्स बनाते हैं - बी-ट्रीज ज्यादातर चीजों के लिए अच्छे होते हैं और रेंज क्वेश्चन को अनुमति देते हैं, लेकिन हैश इंडेक्स आपको सीधे पॉइंट पर ले जाते हैं (लेकिन रेंज की अनुमति नहीं देते हैं)। अन्य प्रकार के अनुक्रमित में अन्य पेशेवरों और विपक्ष हैं।

सौभाग्य!


9

यह सब इस बात पर निर्भर करता है कि आप तालिकाओं के बारे में क्या प्रश्न पूछते हैं यदि आप स्तंभ X के लिए एक निश्चित मान के साथ सभी पंक्तियों के लिए पूछते हैं, तो एक इंडेक्स का उपयोग नहीं किए जाने पर आपको एक पूर्ण तालिका स्कैन करना होगा।

इंडेक्स उपयोगी होंगे यदि:

  • स्तंभ या स्तंभ में उच्च स्तर की विशिष्टता है
  • आपको अक्सर कॉलम के लिए एक निश्चित मूल्य या मानों की श्रेणी देखने की आवश्यकता होती है।

वे उपयोगी नहीं होंगे यदि:

  • आप तालिका में पंक्तियों के बड़े% (> 10-20%) का चयन कर रहे हैं
  • अतिरिक्त स्थान उपयोग एक समस्या है
  • आप सम्मिलित प्रदर्शन को अधिकतम करना चाहते हैं। टेबल पर मौजूद हर इंडेक्स इंसर्ट को कम करता है और परफॉर्मेंस को अपडेट करता है क्योंकि हर बार डेटा चेंज होने पर उन्हें अपडेट किया जाना चाहिए।

प्राथमिक कुंजी कॉलम आमतौर पर अनुक्रमण के लिए महान होते हैं क्योंकि वे अद्वितीय होते हैं और अक्सर पंक्तियों को देखने के लिए उपयोग किए जाते हैं।


स्ट्रिंग खोजें जहां मान स्ट्रिंग के अंदर कहीं भी हो सकता है, यह उस स्थिति में उन सूचकांक का उपयोग नहीं कर सकता है।
आर्थर थॉमस

5

सामान्य तौर पर (मैं mssql का उपयोग नहीं करता हूं इसलिए विशेष रूप से टिप्पणी नहीं कर सकता), प्राथमिक कुंजी अच्छे अनुक्रम बनाती है। वे अद्वितीय हैं और उनके पास एक मूल्य निर्दिष्ट होना चाहिए। (इसके अलावा, प्राथमिक कुंजियाँ ऐसे अच्छे सूचकांक बनाती हैं कि उनके पास सामान्य रूप से स्वचालित रूप से बनाया गया एक सूचकांक होता है।)

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

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

(माफी यदि मैं आपके अन्य प्रश्न में उल्लिखित सामान दोहरा रहा हूं, तो मैं पहले इसके पार नहीं आया था।)


5

तालिका से डेटा निकालने के लिए नियमित रूप से उपयोग किए जाने वाले किसी भी स्तंभ को अनुक्रमित किया जाना चाहिए।

इसमें शामिल हैं: विदेशी कुंजी -

select * from tblOrder where status_id=:v_outstanding

वर्णनात्मक क्षेत्र -

select * from tblCust where Surname like "O'Brian%"

कॉलम को अद्वितीय होने की आवश्यकता नहीं है। वास्तव में आप अपवाद की खोज करते समय बाइनरी इंडेक्स से वास्तव में अच्छा प्रदर्शन प्राप्त कर सकते हैं।

select * from tblOrder where paidYN='N'

विदेशी चाबियों का आपका स्पष्ट उल्लेख वास्तव में मेरे लिए जुड़ने पर विचार करने के लिए चीजों को साफ करता है।
pfabri

3

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

इसके अलावा, मिसिंग इंडेक्स फ़ीचर के बारे में पढ़ें। यह आपके डेटाबेस के खिलाफ उपयोग किए जा रहे वास्तविक प्रश्नों पर नज़र रखता है और आपको बता सकता है कि इंडेक्स ने प्रदर्शन में क्या सुधार किया है।


3

एक GUID कॉलम अनुक्रमण के लिए सबसे अच्छा उम्मीदवार नहीं है। अनुक्रमणिका एक डेटा प्रकार वाले स्तंभों के लिए सबसे उपयुक्त होती है जिन्हें कुछ सार्थक क्रम दिया जा सकता है, जैसे क्रमबद्ध (पूर्णांक, तिथि आदि)।

इससे कोई फर्क नहीं पड़ता कि किसी कॉलम में डेटा आम तौर पर बढ़ रहा है। यदि आप कॉलम पर एक इंडेक्स बनाते हैं, तो इंडेक्स यह खुद का डेटा स्ट्रक्चर बनाएगा जो स्टोर किए गए ऑर्डर (बिना-क्लस्टर किए इंडेक्स) के लिए चिंता किए बिना आपकी टेबल में वास्तविक वस्तुओं का संदर्भ देगा। फिर उदाहरण के लिए तेजी से पुनर्प्राप्ति प्रदान करने के लिए आपके सूचकांक डेटा संरचना पर एक बाइनरी खोज की जा सकती है।

"क्लस्टर इंडेक्स" बनाना भी संभव है जो आपके डेटा को भौतिक रूप से पुनः व्यवस्थित करेगा। हालाँकि, आपके पास इनमें से प्रत्येक तालिका केवल एक हो सकती है, जबकि आपके पास कई गैर-संकुल अनुक्रमणिकाएँ हो सकती हैं।


खैर, यह पूरी तरह से सही नहीं है। आप GUID कॉलम पर एक नियमित, गैर-संकुलित सूचकांक आसानी से बना सकते हैं - क्यों नहीं? GUID में एक बड़ी खामी है यदि आप इसे क्लस्टरिंग कुंजी (उदाहरण के लिए CLUSTERED INDEX) के रूप में उपयोग करते हैं - तो यह उपयोग करने के लिए एक डीस्टर है।
०२

1

अंगूठे का राज 'कॉलम था जो WHERE, ORDER BY, और GROUP BY क्लॉज में बहुत उपयोग किया जाता है, या ऐसा कोई भी जो अक्सर जुड़ने में इस्तेमाल किया जाता था। ध्यान रखें कि मैं अनुक्रमणिका की बात कर रहा हूं, प्राथमिक कुंजी की नहीं

'वेनिला-ईश' उत्तर देने के लिए नहीं, लेकिन यह वास्तव में इस बात पर निर्भर करता है कि आप डेटा कैसे एक्सेस कर रहे हैं


1

आपकी प्राथमिक कुंजी हमेशा एक सूचकांक होनी चाहिए। (मुझे आश्चर्य होगा कि यदि यह MS SQL द्वारा स्वचालित रूप से अनुक्रमित नहीं किया गया था, तो वास्तव में।) आपको स्तंभों को भी अनुक्रमणित करना चाहिए SELECTयाORDER बार-बार ; उनका उद्देश्य एकल मूल्य और त्वरित छंटाई दोनों है।

tooकई स्तंभों को अनुक्रमित करने में एकमात्र वास्तविक खतरा बड़ी तालिकाओं में पंक्तियों में परिवर्तन को धीमा कर रहा है, क्योंकि सभी अनुक्रमितों को भी अद्यतन करने की आवश्यकता होती है। यदि आप वास्तव में यह सुनिश्चित नहीं कर पा रहे हैं कि आपके सबसे धीमे प्रश्नों के बार क्या सूचकांक है, तो देखें कि कौन से कॉलम सबसे अधिक बार उपयोग किए जा रहे हैं, और उन्हें अनुक्रमित करें। फिर देखें कि वे कितने तेज हैं।


1

संख्यात्मक डेटा प्रकार जो आरोही या अवरोही क्रम में दिए गए हैं, कई कारणों से अच्छे सूचकांक हैं। सबसे पहले, संख्याएं आम तौर पर स्ट्रिंग्स (वर्चर, चार, नावरचर, आदि) की तुलना में अधिक तेज़ होती हैं। दूसरा, यदि आपके मूल्यों का आदेश नहीं दिया गया है, तो आपकी अनुक्रमणिका को अद्यतन करने के लिए पंक्तियों और / या पृष्ठों को फेरबदल करने की आवश्यकता हो सकती है। वह अतिरिक्त उपरि है।

यदि आप SQL सर्वर 2005 का उपयोग कर रहे हैं और यूनीकॉलीफायर्स (गिड्स) का उपयोग कर सेट कर रहे हैं, और उन्हें यादृच्छिक प्रकृति के होने की आवश्यकता नहीं है, तो क्रमिक अनूठे पहचानकर्ता प्रकार की जाँच करें।

अंत में, यदि आप क्लस्टर किए गए अनुक्रमित के बारे में बात कर रहे हैं, तो आप भौतिक डेटा के प्रकार के बारे में बात कर रहे हैं। यदि आपके पास आपके क्लस्टर किए गए सूचकांक के रूप में एक स्ट्रिंग है, तो वह बदसूरत हो सकता है।


0

यदि आप GUID का उपयोग कर रहे हैं तो यह और भी तेज़ होना चाहिए। मान लीजिए आपके पास रिकॉर्ड हैं

  1. 100
  2. 200
  3. 3000
  4. ....

यदि आपके पास एक अनुक्रमणिका (बाइनरी खोज है, तो आप अनुक्रमिक रूप से O (n) समय की बजाय O (lg n) समय में खोज रहे रिकॉर्ड का भौतिक स्थान खोज सकते हैं। यह इसलिए है क्योंकि आपको पता नहीं है कि आपके पास कौन से रिकॉर्ड हैं। आप तालिका में।


0

सर्वश्रेष्ठ सूचकांक तालिका की सामग्री पर निर्भर करता है और जिसे आप पूरा करने की कोशिश कर रहे हैं।

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

आपको पहले पता लगाना चाहिए कि आप किस डेटा को क्वेरी कर रहे हैं और फिर यह निर्धारित करें कि आपको किस डेटा को अनुक्रमित करने की आवश्यकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.