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