2010-08-24 14 views
6

साइट पर लगभग 70 के रिकॉर्ड प्रदर्शित होने वाली एक तालिका, जिसमें प्रति पृष्ठ 50 रिकॉर्ड दिखाए जाते हैं। क्वेरी पर limit offset,50 के साथ अंकन किया जाता है, और विभिन्न स्तंभों पर रिकॉर्ड का आदेश दिया जा सकता है।नवीनतम रिकॉर्ड का चयन करते समय चयन बहुत धीमा है

नवीनतम पृष्ठों (लगभग 60000 इतना ऑफसेट है) प्रश्नों बहुत धीमी ब्राउज़िंग बनाता है जब पहली पृष्ठों (के बारे में 10x)

इस limit आदेश का उपयोग का एक मुद्दा है ब्राउज़ कर की तुलना में? क्या वही परिणाम प्राप्त करने के अन्य तरीके हैं?

+0

अच्छा सवाल है, मैं कर रहा हूँ इस संबंध में MySQL कैसे काम करता है उससे परिचित नहीं है। – RedFilter

+0

उत्तरों के लिए धन्यवाद, कुछ गति प्राप्त करने की आशा में बाद में इसका परीक्षण करेंगे। – Omiod

उत्तर

7

बड़े ऑफसेट के साथ, MySQL को और अधिक रिकॉर्ड ब्राउज़ करने की आवश्यकता है।

योजना filesort का उपयोग करता है यहां तक ​​कि अगर (जिसका अर्थ है कि सभी रिकॉर्ड ब्राउज़ किया जाना चाहिए), MySQL यह अनुकूलन कर ताकि केवल $offset + $limit शीर्ष रिकॉर्ड हल कर रहे हैं, जो यह बहुत अधिक $offset के निचले मूल्यों के लिए सक्षम बनाता है।

ठेठ समाधान सूचकांक करने के लिए कॉलम आप पर आदेश दे रहे हैं है,, स्तंभों की अंतिम मान रिकॉर्ड और बाद में प्रश्नों में प्रयोग करना पुन: उपयोग इस तरह:

SELECT * 
FROM mytable 
ORDER BY 
     value, id 
LIMIT 0, 10 

जो आउटपुट:

value id 

1  234 
3  57 
4  186 
5  457 
6  367 
8  681 
10  366 
13  26 
15  765 
17  345 -- this is the last one 

अगले पृष्ठ पर पाने के लिए आपको प्रयोग करेंगे:

SELECT * 
FROM mytable 
WHERE (value, id) > (17, 345) 
ORDER BY 
     value, id 
LIMIT 0, 10 

, जिसमें का उपयोग करता है (value, id) पर डेक्स।

बेशक यह मनमाने ढंग से पहुंच पृष्ठों के साथ मदद नहीं करेगा, लेकिन अनुक्रमिक ब्राउज़िंग के साथ मदद करता है।

इसके अलावा, MySQL में देर से पंक्ति लुकअप के साथ कुछ समस्याएं हैं।

SELECT * 
FROM (
     SELECT id 
     FROM mytable 
     ORDER BY 
       value, id 
     LIMIT $offset, $limit 
     ) q 
JOIN mytable m 
ON  m.id = q.id 

अधिक विस्तृत व्याख्या के लिए यह लेख देखें:: स्तंभों अनुक्रमित रहे हैं, तो इसे इस तरह आपकी क्वेरी को फिर से लिखने की कोशिश कर रहा लायक हो सकता है

+0

MySQL उस tuple-style वाक्यविन्यास ('(val1, val2)> (1, 2)') का समर्थन करता है? मैंने पहले कभी नहीं देखा है। Combiner क्या है (और, मैं मान रहा हूँ)? मुझे लगता है कि आप हर दिन कुछ नया सीखते हैं ... – ircmaxell

+0

@ircmaxell: हाँ यह करता है। यह लेक्सिकोोग्राफ़िकल ऑर्डर है, 'वैल 1> 1 या (वैल 1 = 1 और वैल 2> 2)' – Quassnoi

+0

अच्छा जवाब। यहां एक प्रेजेंटेशन है जो मुझे लगता है कि कुछ अच्छी जानकारी है जो एक ही पंक्ति के साथ है: http://www.slideshare.net/Eweaver/efficient-pagination-using-mysql – nathan

2

यह है कि MySQL सीमाओं से कैसे निपटता है। यदि यह एक इंडेक्स को सॉर्ट कर सकता है (और क्वेरी काफी सरल है) तो यह पहली offset + limit पंक्तियों को खोजने के बाद खोजना बंद कर सकती है। तो LIMIT 0,10 का अर्थ है कि यदि क्वेरी पर्याप्त सरल है, तो इसे केवल 10 पंक्तियों को स्कैन करने की आवश्यकता हो सकती है। लेकिन LIMIT 1000,10 का अर्थ है कि कम से कम पर इसे 1010 पंक्तियों को स्कैन करने की आवश्यकता है। बेशक, स्कैन की जाने वाली पंक्तियों की वास्तविक संख्या कई अन्य कारकों पर निर्भर करती है। लेकिन यहां बिंदु यह है कि limit + offset जितना कम होगा, पंक्तियों की संख्या पर निचले बाउंड को स्कैन करने की आवश्यकता है ...

कामकाज के लिए, मैं आपके प्रश्नों को अनुकूलित करूँगा ताकि क्वेरी स्वयं LIMIT खंड के बिना जितना संभव हो उतना कुशल है। EXPLAIN क्या आप इस मामले में दोस्त हैं ...

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