2010-12-07 14 views
10

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

विचार यह है कि अक्सर, इंडेक्स को लाभ के मुकाबले समान या अधिक लागत होती है। ध्यान दें कि यह प्रश्न indexed-view-vs-indexes-on-table से अलग है क्योंकि प्रेरणा न केवल रिपोर्टिंग है।

क्या यह सच है? क्या यह इंडेक्स-प्यूरिज्म इसके लायक है?

अपने करियर में आप आमतौर पर इंडेक्स का उपयोग करने से बचते हैं?

इंडेक्स के संबंध में सामान्य बड़े पैमाने पर सिफारिशें क्या हैं?

वर्तमान में और आखिरी कंपनी में हम SQL सर्वर का उपयोग करते हैं, इसलिए किसी भी उत्पाद विशिष्ट दिशानिर्देशों का भी स्वागत है।

+4

* खतरनाक * से आपका क्या मतलब है? मुझे नहीं लगता कि किसी भी मानव जीवन पर कोई फर्क नहीं पड़ता कि आप किसी टेबल पर कितनी अनुक्रमणिका डालते हैं। –

+2

ऐसा लगता है जैसे "थोड़ा ज्ञान एक खतरनाक चीज है": बहुत समय पहले, मेरे नियोक्ता के सीईओ ने सोर्ससेफ के साथ समस्याओं के बारे में एक लेख पर ठोकर खाई थी। अगले हफ्ते, ऑन हाई से किसी भी प्रकार के संस्करण नियंत्रण पर प्रतिबंध लगा दिया गया था, क्योंकि यह "खतरनाक" है। आनंद शुरू हो गयी। – Piskvor

+1

@marc_s: आपको लगता है? मुझे इसके बारे में पता नहीं है, मैंने अपने देव बॉक्स पर एक अवैध एसवीएन सर्वर चलाने और वहां ट्रैक रखने का सहारा लिया है। 'file.php',' file1.php', 'file1_.php',' file_20071101.php' और/या 'file_1piskvor.php' आधिकारिक "संस्करण" योजना थी (यानी इसे वास्तविक चीज़ से अलग नाम दें ; बैकअप? हमें कोई स्टीकिंग बैकअप की आवश्यकता नहीं है!)। अप्रत्याशित परिणाम: "सीईओ फिर से 'ऑप्टिमाइजिंग' चला गया और अब ऐप टूटा हुआ है। क्या आपके पास कुछ फाइलें हैं, ये जानी चाहिए, उन फ़ाइलों के लिए पिछले संस्करण, विंक विंक, नज नज?" (हम कई सालों बाद अंततः एक वास्तविक एसवीएन सर्वर प्राप्त करने में कामयाब रहे)। – Piskvor

उत्तर

27

आपको उतनी ही अनुक्रमणिका बनाने की आवश्यकता है जितनी आपको बनाने की आवश्यकता है। न आधिक न कम। यह बहुत ही सरल है।

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

मैं एक उदाहरण साझा करना चाहता हूं जिसे मैंने अभी अपने 2 साल पुराने पीसी पर बनाया है, एक मानक MySQL स्थापना का उपयोग कर। मुझे पता है कि आपने प्रश्न SQL सर्वर को टैग किया है, लेकिन उदाहरण आसानी से परिवर्तित किया जाना चाहिए। मैं 1,000,000 पंक्तियों को तीन तालिकाओं में डालता हूं। बिना इंडेक्स, एक इंडेक्स और नौ इंडेक्स के साथ एक तालिका।

drop table numbers; 
drop table one_million_rows; 
drop table one_million_one_index; 
drop table one_million_nine_index; 

/* 
|| Create a dummy table to assist in generating rows 
*/ 
create table numbers(n int); 

insert into numbers(n) values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); 

/* 
|| Create a table consisting of 1,000,000 consecutive integers 
*/ 
create table one_million_rows as 
    select d1.n + (d2.n * 10) 
       + (d3.n * 100) 
       + (d4.n * 1000) 
       + (d5.n * 10000) 
       + (d6.n * 100000) as n 
     from numbers d1 
      ,numbers d2 
      ,numbers d3 
      ,numbers d4 
      ,numbers d5 
      ,numbers d6; 


/* 
|| Create an empty table with 9 integer columns. 
|| One column will be indexed 
*/ 
create table one_million_one_index(
    c1 int, c2 int, c3 int 
    ,c4 int, c5 int, c6 int 
    ,c7 int, c8 int, c9 int 
    ,index(c1) 
); 

/* 
|| Create an empty table with 9 integer columns. 
|| All nine columns will be indexed 
*/ 
create table one_million_nine_index(
    c1 int, c2 int, c3 int 
    ,c4 int, c5 int, c6 int 
    ,c7 int, c8 int, c9 int 
    ,index(c1), index(c2), index(c3) 
    ,index(c4), index(c5), index(c6) 
    ,index(c7), index(c8), index(c9) 
); 


/* 
|| Insert 1,000,000 rows in the table with one index 
*/ 
insert into one_million_one_index(c1,c2,c3,c4,c5,c6,c7,c8,c9) 
select n, n, n, n, n, n, n, n, n 
    from one_million_rows; 

/* 
|| Insert 1,000,000 rows in the table with nine indexes 
*/ 
insert into one_million_nine_index(c1,c2,c3,c4,c5,c6,c7,c8,c9) 
select n, n, n, n, n, n, n, n, n 
    from one_million_rows; 

मेरे समय कर रहे हैं: अनुक्रमणिका बिना तालिका में

  • 1m पंक्तियों: 0,45 सेकंड 1 सूचकांक के साथ तालिका में
  • 1m पंक्तियों: 1,5 सेकंड
  • तालिका में
  • 1m पंक्तियों 6,98 सेकंड

मैं सांख्यिकी और गणित की तुलना में एसक्यूएल के साथ बेहतर हूँ, लेकिन मुझे लगता है कि लगता है कि करने के लिए करना चाहते हैं::सूचकांकमेरी तालिका में 8 इंडेक्स जोड़ना, कुल मिलाकर 6,48 सेकंड जोड़ा गया (6,98-1,5)। प्रत्येक सूचकांक ने सभी 1,000,000 पंक्तियों के लिए 0,685 सेकंड (5,48/8) का योगदान दिया होगा। इसका मतलब यह होगा कि प्रति इंडेक्स प्रति पंक्ति जोड़ा गया ओवरहेड 0,000000685 सेकेंड होगा। कुछ लोग निर्देशकों के बोर्ड को कॉल करते हैं!

निष्कर्ष में, मैं कहना चाहूंगा कि उपरोक्त परीक्षण केस एक छल साबित नहीं करता है। यह सिर्फ आज रात दिखाता है, मैं एक एकल उपयोगकर्ता वातावरण में एक तालिका में लगातार 1,000,000 पूर्णांक डालने में सक्षम था। आपके परिणाम अलग होंगे।

+0

सुंदर स्पष्टीकरण .. – Mac

+0

वाह! हमेशा एक जवाब चाहिए जो * perf-hit * को एक नई अनुक्रमणिका जोड़ता है। इस रोनीस के लिए धन्यवाद! – divyanshm

+0

क्या अधिक बड़ी टेबल के मामले में रिश्तेदार ओवरहेड बदल जाएगा? – Filippos

1

एक इंडेक्स अपडेट करना एक बार प्रति डालने (प्रति इंडेक्स) है। प्रत्येक चयन के लिए गति लाभ है। इसलिए यदि आप बार-बार अपडेट करते हैं और अक्सर पढ़ते हैं, तो अतिरिक्त काम इसके लायक हो सकता है।

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

लेकिन सामान्य सलाह है: यदि आप जानना चाहते हैं कि सबसे तेज़ कौन सा है: प्रोफ़ाइल!

+1

इससे भी बदतर है। उदाहरण के लिए। किसी तालिका-लॉक में गैर-अनुक्रमित कॉलम परिणामों का उपयोग करके एक तालिका (एक-से-कई संबंधों का कई हिस्सा) अपडेट करना, और इसी तरह पढ़ना एक तालिका स्कैन है। इससे बुरी तरह से परेशानी को नुकसान पहुंचाने की गंभीर खुराक हो सकती है। –

0

प्रत्येक तालिका में एक पीके होना चाहिए, जो पाठ्यक्रम (आमतौर पर एक क्लस्टरर्ड) से अनुक्रमित होता है, फिर प्रत्येक एफके को भी अनुक्रमित किया जाना चाहिए।
अंत में आप उन फ़ील्ड को इंडेक्स करना चाहते हैं जिन पर आप अक्सर सॉर्ट करते हैं, यदि उनका डेटा अच्छी तरह से भिन्न है: एक फ़ील्ड के लिए जिसमें 1 मिलियन रिकॉर्ड वाले तालिका में केवल 5 संभावित मान हैं, तो एक सूचकांक एक महान लाभ नहीं होगा ।
मैं सूचकांक के साथ minimalistic होने के लिए, जब तक डीबी अच्छी तरह से भराई शुरू होता है, और ... धीमी। बाधाओं की पहचान करना और उस बिंदु पर इंडेक्स को सही करना आसान है।

8

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

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

6

हां, निश्चित रूप से - किसी तालिका पर बहुत अधिक अनुक्रमणिका किसी भी इंडेक्स से भी बदतर हो सकती हैं। हालांकि, मुझे नहीं लगता कि "प्रति तालिका सबसे अधिक सूचकांक" नियम होने में कोई अच्छा है।

एसक्यूएल सर्वर के लिए, मेरे नियम है:

  • सूचकांक किसी भी विदेशी कुंजी क्षेत्रों - यह मदद करता है जुड़ जाता है और अन्य प्रश्नों के लिए फायदेमंद है, भी
  • सूचकांक किसी भी अन्य क्षेत्रों है जब यह समझ में आता है, उदाहरण के लिए , DELETE बनाम प्रश्नों को तेज करने के पेशेवरों सम्मिलित करें के बारे में अतिरिक्त भूमि के ऊपर, अद्यतन के विपक्ष वजन - - एक सटीक विज्ञान नहीं है - जब गहन प्रश्नों के बहुत सारे सूचकांकों का सही मिश्रण ढूँढना से यह

फायदा हो सकता है यह जानकारियों, अनुभव, मापने, मापने और मापने के बारे में और जानें।

कोई तय नियम कुछ और की तुलना में अधिक contraproductive होने के लिए बाध्य किया जाता है .....

अनुक्रमण पर सबसे अच्छी सामग्री किम्बर्ली ट्रिप से आता है - अनुक्रमण की रानी - उसके blog posts here देखते हैं।

+0

+1। क्लासिक "यह निर्भर करता है" :)। एफके इंडेक्सिंग को इंगित करने के लिए भी। –

2

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

हमारे पास कुछ टेबल हैं जो लाखों रिकॉर्ड के साथ शायद ही कभी सम्मिलित हैं। इनमें से कुछ टेबल भी काफी व्यापक हैं। इन तालिकाओं के लिए 15+ अनुक्रमणिका होने के लिए असामान्य नहीं है। भारी डालने और कम पढ़ने वाले अन्य टेबलों में हमारे पास केवल कुछ हद तक इंडेक्स हो सकते हैं- लेकिन प्रति तालिका एक सूचकांक पागल है।

+0

आप इसका उत्तर देना चाहेंगे: http://stackoverflow.com/questions/4377986/how-to-index-all-foreign-keys-in-ms-sql – JeffO

1

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

इंडेक्स स्थान लेते हैं ताकि तालिका में बहुत से इंडेक्स बनाने से ऊपर सूचीबद्ध कारणों के लिए उत्पादक काउंटरिव हो सके। 5 इंडेक्स स्कैनिंग और फिर पंक्ति लुकअप करना टेबल स्कैनिंग से कहीं अधिक महंगा हो सकता है।

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

आपकी क्वेरी योजनाओं के साथ प्रयोग यह देखने के लिए करें कि आपका समाधान किसी इंडेक्स के साथ कैसे सुधारता है या घटता है।

1

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

उपयोग करने के लिए कितने अनुक्रमणिका इस बात पर निर्भर करती है कि तालिका का उपयोग कैसे किया जाता है। एक तालिका जिसे अद्यतन किया जाता है, आमतौर पर उसमें से कम इंडेक्स होता है जो इसे अद्यतन होने से कहीं अधिक बार पढ़ा जाता है।

हमारे पास कुछ टेबल हैं जो नियमित रूप से हर दो मिनट में नौकरी से अपडेट होते हैं, लेकिन अक्सर उन प्रश्नों से अक्सर पढ़ा जाता है जो बहुत भिन्न होते हैं, इसलिए उनके पास कई अनुक्रमणिका होती हैं। उदाहरण के लिए एक टेबल में 24 इंडेक्स हैं।

0

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

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