2009-06-22 10 views
7

हाइपोटेटिक रूप से, एक SQL सर्वर डेटाबेस में, यदि मेरे पास दो int फ़ील्ड (कई से कई संबंध कहते हैं) के साथ एक तालिका है जो दो अन्य तालिकाओं के बीच जुड़ने में भाग लेती है, तो तालिका का अनुमानित आकार कितना बड़ा हो जाता है दो int फ़ील्ड पर इंडेक्स का प्रदर्शन लाभ इंडेक्स द्वारा लगाए गए ओवरहेड पर निर्भर करता है?डेटाबेस तालिका कब बड़ी हो जाती है कि एक सूचकांक फायदेमंद है?

क्या SQL सर्वर के विभिन्न संस्करणों के बीच आर्किटेक्चर में अंतर है जो इस उत्तर को काफी हद तक बदल देगा?

उत्तर

10

तालिका पंक्तियों के छोटे हिस्सों से जुड़े प्रश्नों के लिए, सूचकांक हमेशा फायदेमंद होते हैं, 100 पंक्तियां या 1,000,000 हो।

इस तरह के प्रश्नों:

SELECT * 
FROM table1 t1 
JOIN table2 t2 
ON  t2.col = t1.col 

संभवत: HASH JOIN का उपयोग करेगा

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

ऐसा करने के लिए, कोई अनुक्रमणिका की आवश्यकता नहीं है।

हालांकि, इस प्रश्न:

SELECT * 
FROM table1 t1 
JOIN table2 t2 
ON  t2.col = t1.col 
WHERE t1.othercol = @value 

NESTED LOOPS का उपयोग करेगा: बाहरी तालिका (table1) से पंक्तियों table1.othercol पर एक सूचकांक का उपयोग कर खोजा जाएगा, और भीतरी मेज से पंक्तियों (table2) हो जाएगा table2.col पर एक इंडेक्स का उपयोग करके खोजा गया।

यदि आपके पास col1 पर कोई अनुक्रमणिका नहीं है, तो HASH JOIN का उपयोग किया जाएगा जिसके लिए दोनों टेबल और सभी संसाधनों से सभी पंक्तियों को स्कैन करने की आवश्यकता है ताकि हैश तालिका बनाई जा सके।

इंडेक्स इस तरह के प्रश्नों के लिए भी उपयोगी होते हैं:

SELECT t2.col 
FROM table1 t1 
JOIN table2 t2 
ON  t2.col = t1.col 

, जिस स्थिति में इंजन table2 में ही सभी को पढ़ने के लिए की जरूरत नहीं है: eveything आप इस प्रश्न के लिए की जरूरत सूचकांक में पाया जा सकता है , जो तालिका से बहुत छोटा हो सकता है और पढ़ने के लिए और अधिक कुशल हो सकता है।

और, बेशक, अगर आप की जरूरत है अपने डेटा सॉर्ट किया और दोनों table1.col और table2.col सूचक है, तो निम्न क्वेरी:

SELECT * 
FROM table1 t1 
JOIN table2 t2 
ON  t2.col = t1.col 
ORDER BY 
     t2.col 

शायद MERGE JOIN विधि है, जो सुपर तेज है का उपयोग करेगा अगर दोनों इनपुट rowset क्रमबद्ध हैं, और इसका आउटपुट भी सॉर्ट किया गया है, जिसका अर्थ है कि ORDER BY निःशुल्क आता है।

ध्यान दें कि यदि आपके पास कोई अनुक्रमणिका नहीं है, तो भी एक ऑप्टिमाइज़र Eager Spool आपकी छोटी तालिका का चयन कर सकता है, जिसका अर्थ है क्वेरी की अवधि के लिए अस्थायी अनुक्रमणिका बनाना और क्वेरी समाप्त होने के बाद इंडेक्स को छोड़ देना।

यदि क्वेरी छोटी है, तो यह बहुत तेज़ होगा, लेकिन फिर, एक सूचकांक चोट नहीं पहुंचाएगा (SELECT प्रश्नों के लिए मेरा मतलब है)। अगर अनुकूलक को इसकी आवश्यकता नहीं होगी, तो इसका उपयोग नहीं किया जाएगा।

नोट, हालांकि, एक सूचकांक बनाने DML प्रदर्शन को प्रभावित कर सकता है, लेकिन यह अन्य कहानी है।

+0

वास्तव में, डेटाबेस एक ही पृष्ठ के भीतर सॉर्ट कुंजी नहीं करता है। तो जब तक कि उस बिंदु से परे नहीं हो जाता तब तक कोई लाभ नहीं होता है। और शायद उससे परे कई पृष्ठों के लिए। – dkretz

+0

@Robert: जब आप क्वेरी में केवल अनुक्रमित कॉलम का उपयोग करते हैं या जब आपको सॉर्ट करने के लिए अपने डेटा की आवश्यकता होती है तो उन्हें भी लाभ होता है। और नहीं, वे हमेशा चुनिंदा लोगों पर, जहां पर क्लॉज पर लाभ नहीं होते हैं। – Quassnoi

+0

Quassnoi, मैंने आपके ब्लॉग पोस्ट को देखा। बस इतना ही पता है, हमारे डेटाबेस को अनुक्रमणित करने का अंतिम निर्णय (इस पोस्ट पर अतिरिक्त जानकारी के आधार पर: stackoverflow.com/questions/1033796/...) सभी विदेशी कुंजीों को इंडेक्स करना था जो कम से कम 10 में लुकअप टेबल में शामिल होने में भाग लेते हैं रिकॉर्ड करता है। –

0

मुझे विश्वास है कि जैसे ही आप उन int क्षेत्रों में शामिल होना शुरू करते हैं, आपकी तालिका काफी बड़ी है। यदि तालिका इतनी छोटी है कि उसे किसी इंडेक्स से लाभ नहीं होगा तो ओवरहेड इतना महत्वपूर्ण नहीं होगा कि आप ऑप्ट आउट करना चाहें।

जब मैं इंडेक्स के कारण ओवरहेड के बारे में सोचता हूं तो आमतौर पर यह मानता है कि तालिका सूचकांक कितनी बार बदल जाएगा - इंडेक्स किए गए कॉलम में आवेषण, हटाना और अपडेट के माध्यम से।

+0

इंडेक्स केवल एसईसीईटी स्टेटमेंट्स पर ओवरहेड जोड़ते हैं, न केवल INSERT और UPDATEs। –

1

सूचकांक अतिरिक्त स्मृति की लागत और सम्मिलन/हटाने के लिए प्रदर्शन लागत (क्योंकि उस समय सूचकांक को बनाए रखने की आवश्यकता है) पर क्वेरी के प्रदर्शन को हमेशा बढ़ाएगा। प्रोफाइलिंग यह बताने का एकमात्र निश्चित तरीका होगा कि सूचकांक, आपके विशेष मामले में, फायदेमंद है या नहीं।

सामान्य रूप से, जब आप एक इंडेक्स बनाते हैं (प्रविष्टि की अतिरिक्त लागत के अलावा) आप गति के लिए स्मृति की ट्रेडिंग कर रहे हैं। यदि आप डाले गए/हटाए गए पंक्तियों की संख्या के सापेक्ष कई प्रश्न (चयन या अपडेट) कर रहे हैं, तो इंडेक्स आपके प्रदर्शन को हमेशा बढ़ाएंगे।

+0

यदि मामला अपेक्षाकृत मानक है (जैसा कि तालिका में दो इंट्स के उदाहरण में है), टिप-ओवर पॉइंट अपेक्षाकृत स्तर है, या यह बाहरी तालिकाओं में अतिरिक्त कॉलम की संख्या के फ़ंक्शन के रूप में भिन्न होगा, और अन्य अज्ञात कारकों? –

+0

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

+0

इंडेक्सिंग आपके प्रश्नों को लगभग पूरे बोर्ड में तेज करेगी। कॉलम की संख्या थोड़ा अंतर करेगी, क्योंकि यह उचित पंक्तियों को वापस करने की बात है (जो कॉलम की संख्या से कुछ अलग है)। यदि आपके पास बहुत कम डेटा है, तो सूचकांक बहुत मदद नहीं कर सकता है, लेकिन यह लगभग भी मुफ्त है - मैं व्यक्तिगत रूप से हमेशा कॉलम इंडेक्स करता हूं जिसे मैं अक्सर किसी भी स्थान प्रश्नों के लिए उपयोग कर रहा हूं (पंक्तियों को अपडेट करने सहित [जब तक आप नहीं बदलते अनुक्रमित कॉलम), क्योंकि यह अपेक्षाकृत छोटे मामलों में भी एक सूचकांक के साथ बहुत तेज होगा। –

1

यह आपके डेटा की चयनकता पर निर्भर करता है, यदि आपका डेटा पर्याप्त चुनिंदा नहीं है तो सूचकांक का उपयोग भी नहीं किया जा सकता है क्योंकि लागत बहुत महंगी होगी। यदि आपके पास तालिका में केवल 2 मान हैं और इन मानों को समान रूप से वितरित किया गया है तो आपको स्कैन मिलेगा

मुझे अभी भी विश्वास है कि प्रत्येक तालिका में प्राथमिक कुंजी होनी चाहिए, यदि आपके पास है तो आपके पास पहले से ही एक अनुक्रमणिका है

+0

यह सच है कि मेरे hypothetical (कई से कई शामिल) में बाहरी टेबल पहले से ही इंडेक्स होगा। –

+0

एक दो कॉलम जंक्शन तालिका? दो अन्य तालिकाओं से प्राथमिक कुंजी पर कम चयनकता होना बेहद असामान्य होगा। – dkretz

+0

@ रॉबर्ट: आपकी लिंकिंग टेबल के बारे में क्या? इसमें प्राथमिक कुंजी भी होनी चाहिए - यदि कुछ और नहीं, तो दो विदेशी कुंजी कॉलम पर एक समग्र प्राथमिक कुंजी। आपकी वर्तमान स्कीमा आपको डुप्लिकेट रिकॉर्ड से कैसे सुरक्षित रखती है? – GalacticCowboy

1

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

+0

क्या आप कह रहे हैं कि SQL सर्वर केवल इंडेक्स का उपयोग करके निष्पादन योजना तैयार करेगा यदि यह निर्धारित करता है कि सूचकांक लाभ प्रदान करेगा? –

+1

दाएं। एसओ में कई प्रश्न हैं कि क्यों छोटे टेबल पर इंडेक्स का उपयोग नहीं किया जा रहा है, और जवाब "आपके पास अभी तक पर्याप्त डेटा नहीं है।" – dkretz

+0

तो मेरा प्रश्न यह बताता है, "एसक्यूएल सर्वर ऑप्टिमाइज़र इंडेक्स में कितने रिकॉर्ड करता है?" और जवाब है, "परवाह नहीं है?" –

1

कोडिंग प्रदर्शन की अवधारणा के बारे में सोचने की एक और बात है - कभी-कभी एक इंडेक्स होने से डेटा के विभिन्न टुकड़ों के बीच संबंधों को प्रबंधित करने के तरीके के बारे में सोचने के मानसिक ओवरहेड को व्यवस्थित किया जा सकता है। कभी-कभी यह जटिल हो सकता है ...

+0

एक बात मैंने उल्लेख नहीं की है कि मैं लिंक से एसक्यूएल का उपयोग करता हूं, जो कि मॉडल नामों और इंडेक्स को मॉडल में शामिल किए जाने के संकेतों के रूप में लेता है; विशेष रूप से, विदेशी कुंजी में विशेष प्राथमिकता मिलती है। –

1

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

भूमि के ऊपर के बारे में, सवाल बन जाता है: क्या भूमि के ऊपर आप मतलब है, और आप इसे कैसे एक देखने के मूल्य के संबंधित हैं? दोनों अलग-अलग मूल्य हैं, आखिरकार।

वहाँ एक सूचकांक के लिए भूमि के ऊपर के दो प्रकार हैं: डालने पर अंतरिक्ष (जो आमतौर पर नगण्य है, कैसे सूचकांक संरचित है पर निर्भर करता है), और फिर से सूचकांक (सर्वर हर डालने के बाद एक सूचकांक पुनर्गणना चाहिए)।

जैसा कि मैंने उल्लेख किया है, अंतरिक्ष समस्या शायद यह एक बड़ा सौदा नहीं है। लेकिन पुन: अनुक्रमणित है। सौभाग्य से, आपको ओवरहेड के रूप में एक समस्या बनने से पहले बहुत से निरंतर डालने की ज़रूरत है।

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

+0

गलत। केवल एक पंक्ति के साथ एक टेबल बनाएं, एक अनुक्रमणिका जोड़ें, और अपने लिए देखें। –

+0

ठीक है, "आकार के बावजूद" मेरा मतलब है "3 से अधिक पंक्तियों वाले तालिकाओं के लिए"। बेहतर? – Randolpho

+0

क्या टिपोवर पॉइंट वास्तव में तीन रिकॉर्ड है? ऐसा प्रतीत नहीं होता है। –

1
एक बहुत ही उपयोगी लिंक

: "टिपिंग पॉइंट क्वेरी जवाब" http://www.sqlskills.com/BLOGS/KIMBERLY/post/The-Tipping-Point-Query-Answers.aspx

+0

इसके लिए धन्यवाद। यह मुझे बताता है कि कोई निश्चित टिपिंग प्वाइंट नहीं है, कि बहुत से लोगों को इसमें अच्छी अंतर्दृष्टि नहीं है, और यह एक अच्छी बात है कि हमारे पास क्वेरी अनुकूलक हैं। –

1

सबसे अच्छी बात सर्वर पर ही यह आंकड़ा बाहर जाने के लिए है। आप कॉलम में इंडेक्स बनाते हैं जहां यह समझ में आता है (मुझे यकीन है कि पूरे अध्याय हैं यदि पुस्तकें इस तरह से सबसे अच्छा तरीका नहीं है), और एसक्यूएल सर्वर को इंडेक्स का उपयोग कब/कैसे करें।

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

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