2010-05-22 9 views
12

मैं पूरी तरह से इस पर फंस गया हूं। किसी कारण से जब मैं डीईएससी द्वारा इस क्वेरी को सॉर्ट करता हूं तो यह बहुत तेज़ है, लेकिन अगर एएससी द्वारा क्रमबद्ध किया गया तो यह बेहद धीमा है।डीईएससी द्वारा MySQL ऑर्डर तेज है लेकिन एएससी बहुत धीमी है

SELECT posts.id 
FROM posts USE INDEX (published) 
WHERE posts.feed_id IN (4953,622,1,1852,4952,76,623,624,10) 
ORDER BY posts.published DESC 
LIMIT 0, 50; 

इस बारे में 32 सेकंड लेता है:

SELECT posts.id 
FROM posts USE INDEX (published) 
WHERE posts.feed_id IN (4953,622,1,1852,4952,76,623,624,10) 
ORDER BY posts.published ASC 
LIMIT 0, 50; 

व्याख्या दोनों प्रश्नों के लिए एक ही है

यह लगभग 150 मिलीसेकेंड लेता है।

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE posts index NULL published 5 NULL 50 Using where 

मैं इसे "उपयोग सूचकांक (प्रकाशित)" के लिए नीचे ट्रैक करने के बाद। अगर मैं इसे बाहर ले जाता हूं तो यह दोनों तरीकों से एक ही प्रदर्शन है। लेकिन एक्सप्लाइन दिखाता है कि क्वेरी समग्र रूप से कम कुशल है।

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE posts range feed_id feed_id 4 \N 759 Using where; Using filesort 

और यहां तालिका है।

CREATE TABLE `posts` (
    `id` int(20) NOT NULL AUTO_INCREMENT, 
    `feed_id` int(11) NOT NULL, 
    `post_url` varchar(255) NOT NULL, 
    `title` varchar(255) NOT NULL, 
    `content` blob, 
    `author` varchar(255) DEFAULT NULL, 
    `published` int(12) DEFAULT NULL, 
    `updated` datetime NOT NULL, 
    `created` datetime NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `post_url` (`post_url`,`feed_id`), 
    KEY `feed_id` (`feed_id`), 
    KEY `published` (`published`) 
) ENGINE=InnoDB AUTO_INCREMENT=196530 DEFAULT CHARSET=latin1; 

क्या इसके लिए कोई फिक्स है? धन्यवाद!

उत्तर

5

आपका सूचकांक desc क्रमबद्ध किया जाता है तो जब आप आरोही के लिए पूछना यह एक बहुत अधिक काम करने के लिए

+0

स्पष्टीकरण के लिए धन्यवाद। क्या इसे ठीक करने का कोई तरीका है? मैं 2 अलग-अलग प्रश्नों का उपयोग करने के बारे में सोच रहा हूं, यह डीईएससी के लिए और एएससी के लिए एक अलग है। – Pepper

+0

यदि आप mysql 5+ का उपयोग कर रहे हैं तो आप एकाधिक अनुक्रमणिका को परिभाषित करने में सक्षम होना चाहिए। –

+4

http://dev.mysql.com/doc/refman/5 से।5/en/बनाने-index.html: एक index_col_name विनिर्देश एएससी या DESC के साथ समाप्त कर सकते हैं। इन कीवर्ड को आरोही या अवरोही सूचकांक मान संग्रहण निर्दिष्ट करने के लिए भविष्य के एक्सटेंशन के लिए अनुमति है। वर्तमान में, उन्हें पार्स किया गया है लेकिन अनदेखा किया गया है; सूचकांक मूल्य हमेशा आरोही क्रम में संग्रहीत होते हैं। तो, कैसे मैं एक सूचकांक कि desc क्रमबद्ध किया जाता है बना सकते हैं? – a1ex07

0

के बारे में कैसा जहां हालत flipping इसी क्रम में इसे वापस लाने की जरूरत है?

ALTER TABLE posts ADD INDEX (feed_id, published) 

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

SELECT posts.id 
FROM posts USE INDEX (published) 
WHERE posts.feed_id IN (10,624,623,76,4952,1852,622,4953) 
ORDER BY posts.published DESC; 
+1

मुझे समझ में नहीं आ रहा है, क्या आप स्पष्टीकरण दे सकते हैं या एक उदाहरण प्रदान कर सकते हैं? – Pepper

+0

SELECT Posts.id पोस्टों से INDEX का उपयोग करें (प्रकाशित) जहां पोस्ट.feed_id IN (10,624,623,76,4952,1852,622,4953) पोस्ट द्वारा ऑर्डर। प्रकाशित डीईएससी; अच्छी तरह से ... post.created ठीक उसी छँटाई – user184365

0

आप भर में एक सूचकांक (FEED_ID, प्रकाशित) जोड़ना चाहते हैं ।

+0

यह वही है कि मैंने पहले था होना चाहिए, लेकिन 500000+ प्रविष्टियों यह धीरे धीरे प्रदर्शन कर रहा था की एक मेज पर। एएससी – Pepper

+0

द्वारा आदेश दिए जाने पर डीईएससी द्वारा आदेश दिया गया और 10x धीमी गति से ऊपर प्रकाशित सूचकांक को मजबूर करना लगभग 3x तेज है, आपने इस सटीक अनुक्रमणिका को आजमाया है? उस क्रम में? "धीरे धीरे" परिभाषित करें। 500,000+ पंक्तियों वास्तव में MySQL करने के लिए एक बड़ी बात नहीं है (जब तक आपके सर्वर प्राचीन है), और उन दो क्षेत्रों भर में एक सूचकांक के साथ, इस प्रश्न के सभी सूचकांक तरह दिशा की परवाह किए बिना किया जाना चाहिए। आपके "समझ में फाइलों का उपयोग करना" योजना में आपको टिप देना चाहिए - इस तरह के सरल एक-टेबल प्रश्नों को अनुकूलित करते समय ऐसा कोई कारण नहीं होना चाहिए। इसके अलावा, क्या "प्रकाशित" है? क्या कोई अच्छा कारण है कि यह एक int (12) है? –

+0

मुझे लगता है कि "धीरे-धीरे" मेरा मतलब है कि मेरे पास डीईएससी सॉर्टिंग के साथ धीमा है। यह एक प्रकार कर रहा है: सीमा, 50 की बजाय 4000 पंक्तियों को मारना और फाइलॉर्ट का उपयोग कर रहा है। – Pepper

1

मैं सुझाव नहीं दूंगा कि आप तालिका पर एक और अनुक्रमणिका बनाएं; प्रत्येक बार जब कोई पंक्ति डाली जाती है या हटा दी जाती है, तो तालिका पर प्रत्येक अनुक्रमणिका को अद्यतन करने की आवश्यकता होती है, INSERT क्वेरी धीमा कर देती है।

सूचकांक निश्चित रूप से इसे धीमा कर रहा है। हो सकता है कि आप इसे आईएनजी IGNORE की कोशिश कर सकते:

SELECT posts.id 
FROM posts IGNORE INDEX (published) 
WHERE posts.feed_id IN (4953,622,1,1852,4952,76,623,624,10) 
ORDER BY posts.published ASC 
LIMIT 0, 50; 

या, के बाद से क्षेत्र में पहले से ही KEY एड है, तो आपको निम्न कोशिश कर सकते हैं:

SELECT posts.id 
FROM posts USE KEY (published) 
WHERE posts.feed_id IN (4953,622,1,1852,4952,76,623,624,10) 
ORDER BY posts.published ASC 
LIMIT 0, 50; 
+0

धन्यवाद, उपयोग करें और उपयोग करें INDEX का एक ही परिणाम प्रतीत होता है। और यूएसई इंडेक्स का उपयोग नहीं करते हैं, इग्नोर इंडेक्स के समान परिणाम हैं। – Pepper

3

आप अपने डेटा पहले सेट हो सकता है, और फिर आदेश यह।

तरह

SELECT posts.id FROM (
SELECT posts.id 
FROM posts USE INDEX (published) 
WHERE posts.feed_id IN (4953,622,1,1852,4952,76,623,624,10) 
LIMIT 0, 50 
) 
order by postS.id ASC; 

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

सर्वश्रेष्ठ सादर।

+0

धन्यवाद, बीमार कोशिश करो। – Pepper

+1

त्वरित नोट, उपरोक्त उपरोक्त कार्य करने के लिए उपनाम की आवश्यकता है। – Pepper

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