2010-11-03 7 views
9

मेरे पास एक MySQL तालिका है:क्या MySQL आदेश के साथ एक रेंज QUERY में इंडेक्स का उपयोग कर सकते हैं?

CREATE TABLE mytable (
    id INT NOT NULL AUTO_INCREMENT, 
    other_id INT NOT NULL, 
    expiration_datetime DATETIME, 
    score INT, 
    PRIMARY KEY (id) 
) 

मुझे इस रूप में क्वेरी चलाने की आवश्यकता है:

SELECT * FROM mytable 
WHERE other_id=1 AND expiration_datetime > NOW() 
ORDER BY score LIMIT 10 

अगर मैं इस अनुक्रमणिका को mytable में जोड़ता हूं:

CREATE INDEX order_by_index 
ON mytable (other_id, expiration_datetime, score); 

क्या MySQL सक्षम होगा ऊपर दिए गए प्रश्न में पूरे order_by_index का उपयोग करने के लिए?

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

उपर्युक्त मार्ग यह सुझाव देता है कि सूचकांक केवल एक निरंतर क्वेरी में उपयोग किया जाएगा जबकि मेरा एक सीमा प्रश्न है।

क्या कोई इस बात में स्पष्टीकरण दे सकता है कि इस मामले में इंडेक्स का उपयोग किया जाएगा? यदि नहीं, तो मैं किसी भी तरह से सूचकांक के उपयोग को मजबूर कर सकता हूं?

धन्यवाद।

उत्तर

8

MySQL इंडेक्स का उपयोग करके जहां खंड को पूरा करने के होंगे, और परिणाम ऑर्डर करने के लिए एक filesort का प्रयोग करेंगे।

यह आदेश के लिए इंडेक्स का उपयोग नहीं कर सकता क्योंकि आप समाप्ति_डेटाइम की स्थिरता की तुलना नहीं कर रहे हैं। इसलिए, वापस आने वाली पंक्तियों में इंडेक्स में हमेशा एक सामान्य उपसर्ग नहीं होगा, इसलिए इंडेक्स को इस प्रकार इस्तेमाल नहीं किया जा सकता है। अगर मैं 2010-11-03 11:00 पर आपकी क्वेरी चलाने

a) [1,'2010-11-03 12:00',1] 
b) [1,'2010-11-03 12:00',3] 
c) [1,'2010-11-03 13:00',2] 
d) [2,'2010-11-03 12:00',1] 

, यह पंक्तियाँ वापस आ जाएगी एक, सी, डी:

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

+1

>> यह द्वारा क्योंकि आप एक निरंतर करने के लिए expiration_datetime की तुलना नहीं कर रहे हैं आदेश के लिए सूचकांक का उपयोग नहीं कर सकते हैं। << मुझे लगता है कि यहां एक गलती है। हालांकि आपने उत्तर के दूसरे भाग में इसका कारण स्पष्ट रूप से समझाया था। – kellogs

3

लगता है जैसे आप पहले ही प्रलेखन की जांच कर चुके हैं और इंडेक्स सेट अप कर चुके हैं। व्याख्या और देखो का उपयोग करें ...

EXPLAIN SELECT * FROM mytable 
WHERE other_id=1 AND expiration_datetime > NOW() 
ORDER BY score LIMIT 10 
7

क्या कोई इस बात में स्पष्टीकरण दे सकता है कि इस मामले में इंडेक्स का उपयोग किया जाएगा या नहीं? यदि नहीं, तो मैं किसी भी तरह से सूचकांक के उपयोग को मजबूर कर सकता हूं?

आपके पास फ़िल्टरिंग की स्थिति में एक सीमा है और ORDER BY सीमा से मेल नहीं खाता है।

इन शर्तों को एक ही इंडेक्स के साथ परोसा नहीं जा सकता है।

जो सूचकांक बनाने के लिए चुनने के लिए, आप इन प्रश्नों

SELECT COUNT(*) 
FROM mytable 
WHERE other_id = 1 
     AND (score, id) < 
     (
     SELECT score, id 
     FROM mytable 
     WHERE other_id = 1 
       AND expiration_datetime > NOW() 
     ORDER BY 
       score, id 
     LIMIT 10 
     ) 

और

SELECT COUNT(*) 
FROM mytable 
WHERE other_id = 1 
     AND expiration_datetime >= NOW() 

चलाने के लिए और उनके outputs तुलना करने के लिए की जरूरत है।

यदि दूसरी क्वेरी पहले के समान या अधिक मानों के बारे में उत्पन्न होती है, तो आपको (other_id, score) पर एक अनुक्रमणिका का उपयोग करना चाहिए (और इसे expiration_datetime पर फ़िल्टर करना चाहिए)।

यदि दूसरी क्वेरी पहले की तुलना में काफी कम मूल्य उत्पन्न करती है, तो आपको (other_id, expiration_datetime) पर एक इंडेक्स का उपयोग करना चाहिए (और इसे score पर सॉर्ट करना चाहिए)।

यह लेख आपके लिए दिलचस्प हो सकता है:

+0

चुनिंदाता की जांच करने के लिए आपको अलग-अलग मानों की जांच करने की आवश्यकता है, इसलिए COUNT DISTINCT करना न भूलें। –

+0

@AllTheCode: 'COUNT DISTINCT' क्या पर? – Quassnoi

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