डेटाबेस अनुक्रमित [बंद] के साथ पालन करने के लिए सर्वोत्तम अभ्यास


17

सूचकांक का उपयोग करके डेटाबेस प्रदर्शन में सुधार के लिए कुछ डीओ और डॉंट्स क्या हैं?

डीओ एक ऐसा मामला होगा जिसमें एक इंडेक्स बनाया जाना चाहिए, या एक अन्य इंडेक्स संबंधित टिप जो प्रदर्शन में सुधार करेगा।

DONT एक ऐसा मामला होगा जब कोई इंडेक्स नहीं बनाया जाना चाहिए, या कोई अन्य इंडेक्स संबंधित कार्रवाई जो प्रदर्शन को नुकसान पहुंचा सकती है।


3
प्रोफाइल, प्रोफाइल, प्रोफाइल
ग्रैंडमास्टरबी

जवाबों:


15

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

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

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

ट्यूनिंग क्वेरी और डेटाबेस पर किताबें होती हैं, जो अक्सर एक डेटाबेस सिस्टम के लिए विशिष्ट होती हैं और उस RDBMS के टूल का उपयोग करती हैं। यदि आप अपने आप को डेटाबेस का अनुकूलन करने की आवश्यकता पाते हैं, हालांकि, आप एक बड़ा ऑपरेशन चला रहे हैं और संभवत: उचित विशेषज्ञता के साथ डीबीए को किराए पर लेना चाहिए।


17

यह अत्यधिक इस बात पर निर्भर करता है कि आप अपनी तालिकाओं का उपयोग कैसे करते हैं। कोई एकल और सरल उत्तर नहीं है।

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

वे SQL सर्वर और Oracle के लिए मौजूद हैं । मुझे नहीं पता कि अन्य डीबीएमएस उनके पास है, बस मुझे संदेह है कि वे ऐसे बुनियादी उपकरण प्रदान नहीं करते हैं।

कुछ यादृच्छिक सिफारिशें:

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

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


2
स्तंभों के संयोजन पर अनुक्रमित के लिए +1। स्तंभों पर इंडेक्स aऔर bहै नहीं पर एक सूचकांक के रूप में ही (a, b)। बाद लगभग पर सूचकांक के रूप में अच्छा के रूप में है aपर एक शर्त के साथ प्रश्नों को तेज करने के लिए a, पर बड़े पैमाने पर शर्तों के साथ प्रश्नों के लिए बेहतर है aऔर b, और पर प्रश्नों के लिए उपयोगी नहीं है bअकेले। (अधिकांश
काउंटी

2
+1, "क्वेरी को पढ़ना सीखना सीखेंगे ताकि आपको पता चल सके कि सूचकांक क्या है"
स्टीवन ए। लोवे

4

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

अपने डेटाबेस का समर्थन करता है, तो डीओ कार्यों कि कॉलम प्रश्नों के बजाय में दिखाने पर अनुक्रमित डाल दिया। (यदि आप किसी स्तंभ पर कोई फ़ंक्शन कॉल कर रहे हैं, तो उस स्तंभ पर अनुक्रमणिका बेकार हैं।)

आप सच अस्थायी तालिकाओं के साथ एक डेटाबेस का उपयोग कर रहे हैं कि आप बना सकते हैं और मक्खी पर नष्ट (जैसे PostgreSQL, MySQL, लेकिन नहीं ओरेकल), तो करते अस्थायी टेबल पर अनुक्रमणिका बनाएँ।

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

आपके पास एक बड़ा डेटा लोड करने के लिए तालिकाओं पर अनुक्रमित नहीं हैं। यह इंडेक्स को छोड़ने, डेटा को लोड करने के लिए बहुत तेज है, फिर इंडेक्स को फिर से बनाए रखने की तुलना में उन्हें बनाए रखने के लिए जैसे ही आप टेबल को लोड करते हैं।

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

SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
  JOIN big_table
    ON big_table.small_table_id = small_table.id
GROUP BY small_table.id

3 मिनट से इसे फिर से लिखना इस प्रकार है:

SELECT small_table.id, big_table_summary.summed_value
FROM small_table
  JOIN (
      SELECT small_table_id, SUM(some_value) as summed_value
      FROM big_table
      GROUP BY small_table_id
    ) big_table_summary
    ON big_table_summary.small_table_id =  small_table.id

जो डेटाबेस को यह समझने के लिए मजबूर करता है कि उसे परीक्षा सूचकांक का उपयोग करने का प्रयास नहीं करना चाहिए big_table.small_table_id। (एक अच्छा डेटाबेस, जैसे ओरेकल, को यह पता लगाना चाहिए कि यह क्वेरी MySQL पर चल रही है।)

अपडेट: यहां डिस्क की तलाश का एक बिंदु है जो मैंने बनाया है। एक इंडेक्स यह कहने के लिए एक त्वरित खोज देता है कि डेटा टेबल में कहां है। यह आमतौर पर एक जीत है क्योंकि आप केवल उस डेटा को देखेंगे जिसे आपको देखने की आवश्यकता है। लेकिन हमेशा नहीं, खासकर यदि आप अंततः बहुत अधिक डेटा देखेंगे। डेटा को अच्छी तरह से स्ट्रीम करता है, लेकिन लुकअप धीमा कर देता है। डिस्क पर डेटा के लिए एक यादृच्छिक लुकअप सेकंड का 1/200 वां हिस्सा लेता है। क्वेरी का धीमा संस्करण 600,000 लोगों की तरह कुछ कर रहा है और एक घंटे के करीब लिया। (यह उस से अधिक लुकअप किया, लेकिन कैशिंग ने उनमें से कुछ को पकड़ लिया।) इसके विपरीत तेज संस्करण को पता था कि उसे सब कुछ पढ़ना है और 70 एमबी / सेकंड जैसी किसी चीज़ पर डेटा प्रवाहित करना है। यह 3 मिनट के भीतर 11 जीबी टेबल के माध्यम से मिला।


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

@ क्लिक करें: यदि कोई क्वेरी किसी तालिका के 5% से अधिक (हार्डवेयर और डेटा पर सटीक रूप से निर्भर अंश) तक पहुँचती है, तो उस क्वेरी के लिए किसी इंडेक्स का उपयोग नहीं करना तेज़ होता है। जब तक आप इसका उपयोग नहीं करते हैं, तब तक सूचकांक में चोट नहीं लगती है। मैं अधिक विवरण के साथ अपडेट करूंगा कि ऐसा क्यों है।
btilly

उपयोगी जानकारी। इस पर अधिक उदाहरण के लिए mysqlperformanceblog.com/2007/08/28/… लेकिन मैं सोच रहा था, क्या 'इस बात को अनदेखा करना' इस पर निर्भर नहीं था कि आपको इसे एक उपश्रेणी बनाने की आवश्यकता है?
इंका

@ इंका: मुझे 'उपेक्षा कुंजी' की जानकारी नहीं थी। मैं डेटाबेस को पर्याप्त रूप से स्विच करता हूं कि अक्सर डेटाबेस विशिष्ट चीजें होती हैं जिनके बारे में मुझे जानकारी नहीं है। यह लगता है कि काम करेगा, लेकिन मेरे घटना समाधान की तुलना में काफी कम कुशलता से। अंतर यह है कि तब समूह शामिल होगा, जबकि मेरा समूह, फिर शामिल हो गया। यह जुड़ने पर काम बचाता है क्योंकि कम रिकॉर्ड में शामिल होने की आवश्यकता होती है।
btilly

"एक अच्छा डेटाबेस (उदाहरण के लिए ओरेकल, लेकिन माईएसक्यूएल नहीं)": कृपया, इस तरह बेवकूफ प्रचारक सामान से बचें, खासकर जब आप इस तथ्य को अनदेखा करते हैं कि माईक्यूक एक ही समय में कई सूचकांक का उपयोग कर सकते हैं (क्वेरी योजनाओं में "INDEX MERGE") ।
बजे पैट्रिक अल्जर्ट

2

DO: उन बहुत कम क्षेत्रों को अनुक्रमित करें जिन्हें आप क्वेरी और / या तुलना के माध्यम से सबसे अधिक एक्सेस करते हैं।

DON'T: टेबल के हर क्षेत्र को यह सोचकर इंडेक्स करेगा कि यह तेजी से आगे बढ़ेगा।

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


2

मूल रूप से, सूचकांक खोज की गति बढ़ाते हैं, लेकिन लेखन को धीमा करते हैं, और वे जगह लेते हैं। वह ट्रेड-ऑफ बनाया जा रहा है।

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

पाठ फ़ील्ड के लिए, आप फ़ील्ड के एक भाग (उदाहरण के लिए, पहले 6 वर्ण) पर अनुक्रमण कर सकते हैं, जो आपकी क्वेरी को गति देगा लेकिन सूचकांकों पर भार को हल्का करेगा। पूर्ण पाठ खोज (पर खोज like %substring%) के लिए विभिन्न तकनीकों की आवश्यकता होती है, जिनसे मैं परिचित नहीं हूं, इसलिए मैं आपको वहां सलाह नहीं दे सकता।

एक महत्वपूर्ण स्थिति जहां सूचकांक मदद करने के लिए नहीं जा रहे हैं: जब आप खोज (/ ज्वाइन / ऑर्डर) करते हैं तो डेट के हिस्से पर पूर्ण तिथि या डेटाइम फ़ील्ड के इंडेक्स का उपयोग नहीं कर सकते हैं। एक अनुक्रमणिका date_createdआपकी तरह क्वेरी के साथ मदद नहीं करेगी select * from t where year(date_created) = 2011। Mysql में आप दिनांक के भाग पर एक इंडेक्स नहीं बना सकते हैं। (जब आप इसके betweenबजाय ' ' का year()उपयोग करते हैं तो यह दिनांक फ़ील्ड पर अनुक्रमणिका का उपयोग कर सकता है।)

मैनुअल में MYSQL के बारे में अधिक जानकारी: http://dev.mysql.com/doc/refman/5.6/en/optimization-indexes.html


1

DO: क्लस्टर इंडेक्स के कुल आकार को न्यूनतम रखने की कोशिश करें। क्लस्टर किए गए इंडेक्स प्रविष्टियों को अन्य गैर-क्लस्टर इंडेक्स में शामिल किया जाएगा और यहां से डिस्क स्थान को बर्बाद करने की क्षमता आती है।


1

एक तालिका को लेक्सिकॉन के रूप में सोचें, जहां लेख उपस्थिति के क्रम द्वारा क्रमबद्ध किए गए हों (या कोई सहायक आदेश नहीं), और उस लेक्सिकॉन के लिए पुस्तक सूचकांक के रूप में तालिका सूचकांक।

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

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

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

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