2013-07-23 4 views
6

एक सरल लेकिन बहुत बड़ी InnoDB तालिका पर, मैं स्तंभ एक पर एक अद्वितीय सूचकांक है और मैं (पूर्णांक) स्तंभ एकअद्वितीय अनुक्रमणिका मौजूद होने पर MySQL Innodb "सॉर्ट इंडेक्स बनाना" क्यों है?

बहुत ही सरल प्रश्न के क्रम में (पूर्णांक) स्तंभ बी की एक सूची प्राप्त करना चाहते हैं, मैं कर रहा हूँ लाखों रिकॉर्ड के माध्यम से पेजिंग।

SELECT B FROM hugeTable ORDER BY A LIMIT 10000 OFFSET 500000

यह एक बहुत ही तेजी से सर्वर पर क्वेरी के साथ 10 सेकंड लेता है?

Filesort: Yes Filesort_on_disk: Yes Merge_passes: 9

यह मेरे लिए कोई मतलब नहीं है, यह सूचकांक एक क्यों उपयोग नहीं कर सकते?

समझाएं सरल, कोई संभावित कुंजी और फाइलॉर्ट दिखाता है।

उत्तर

10

यदि कॉलम बी के मान इंडेक्स पृष्ठों में उपलब्ध नहीं हैं, तो MySQL को अंतर्निहित तालिका में पृष्ठों तक पहुंचने की आवश्यकता होगी। इसके अलावा कोई अनुमान नहीं है कि कौन सी पंक्तियों पर विचार किया जा रहा है, और इसका मतलब है कि MySQL देख रहा है कि सभी पंक्तियों को वापस करने की आवश्यकता है। यह समझा सकता है कि सूचकांक का उपयोग क्यों नहीं किया जा रहा है।

यह भी ध्यान दें कि LIMIT ऑपरेशन को कुछ अपवादों के साथ निष्पादन योजना में लगभग अंतिम चरण के रूप में, कथन के अंत में संसाधित किया जाता है।

8.2.1.3. Optimizing LIMIT Queries http://dev.mysql.com/doc/refman/5.5/en/limit-optimization.html

मुझे लगता है कि आपकी क्वेरी, एक कवर सूचकांक का उपयोग कर सकता उदाहरण के लिए "ON hugetable (A,B)", तरह आपरेशन से बचने के लिए।

एक कवरिंग इंडेक्स अनुपस्थित है, तो आप इस तरह की क्वेरी को फिर से लिखने का प्रयास कर सकते हैं, यह देखने के लिए कि क्या यह कॉलम ए पर इंडेक्स का उपयोग करेगा, और लाखों पंक्तियों पर एक प्रकार के ऑपरेशन से बचें (पहली 510,000 पंक्तियां वापस पाने के लिए आदेश) में:

SELECT i.B 
    FROM (SELECT j.A 
      FROM hugeTable j 
      ORDER 
      BY j.A 
      LIMIT 10000 OFFSET 500000 
     ) k 
    JOIN hugetable i 
    ON i.A = k.A 
ORDER 
    BY k.A 

मैं तुम सिर्फ इनलाइन दृश्य क्वेरी पर एक EXPLAIN कर सुझाव देते हैं (के रूप में एलियास), और देखें कि क्या यह पता चलता है "Using index।"

बाहरी क्वेरी में अभी भी "Using filesort" ऑपरेशन होने की संभावना है, लेकिन कम से कम यह केवल 10,000 पंक्तियों पर होगी।

(ध्यान दें: आप बाहरी क्वेरी पर "k.A" के स्थान पर एक "ORDER BY i.A" प्रयास करें, और देखने के लिए चाहते हो सकता है कि अगर एक फर्क नहीं पड़ता।)


परिशिष्ट

विशेष रूप से आपके प्रश्न को संबोधित नहीं करते हैं, लेकिन उस क्वेरी के प्रदर्शन के संदर्भ में, यदि यह पंक्तियों के एक सेट के माध्यम से "पेजिंग" है, तो "अगला" पृष्ठ प्राप्त करने के लिए विचार करने का दूसरा विकल्प "A" के मान का उपयोग करना है पिछली पंक्ति पर पिछली पंक्ति को टी के लिए "प्रारंभ बिंदु" के रूप में पुनर्प्राप्त किया गया वह अगली पंक्ति।

मूल क्वेरी ऐसा लगता है कि यह "पृष्ठ 51" (प्रति पंक्ति 10,000 पंक्तियां, पृष्ठ 51 520,000 के माध्यम से 510,001 पंक्तियां होगी)।

यदि आप 'ए' के ​​मान को भी वापस कर रहे थे, और उसे अंतिम पंक्ति के लिए रखें।"अगले" पृष्ठ पाने के लिए, क्वेरी वास्तव में हो सकता है:

SELECT i.B, k.A 
    FROM (SELECT j.A 
      FROM hugeTable j 
      WHERE j.A > $value_of_A_from_row_520000 
     -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
      LIMIT 10000 
     ) k 
    JOIN hugetable i 
    ON i.A = k.A 
    ORDER 
    BY k.A 

साथ-साथ आप "पहली" पंक्ति से एक के लिए मूल्य रखा है, तो आप इस्तेमाल कर सकते हैं कि एक पृष्ठ का बैकअप लेने के लिए। यह वास्तव में केवल एक पृष्ठ, या एक पृष्ठ के लिए काम करेगा। एक अलग पृष्ठ पर कूदते हुए, पंक्तियों की गिनती, क्वेरी के मूल रूप का उपयोग करना होगा।

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