2011-12-25 11 views
5

मैं इस प्रश्न के साथ एक समस्या है:अनुक्रमित अनुकूलन mysql क्वेरी का उपयोग

SELECT DISTINCT s.city, pc.start, pc.end 
FROM postal_codes pc LEFT JOIN suspects s ON (s.postalcode BETWEEN pc.start AND  pc.end) 
WHERE pc.user_id = "username" 
ORDER BY pc.start 

संदिग्ध तालिका के बारे में 340 000 प्रविष्टियां हैं, तो वहाँ का डाक कोड पर एक सूचकांक है, मैं कई उपयोगकर्ताओं है, लेकिन यह व्यक्तिगत क्वेरी के बारे में 0.5 लेता है एस, जब मैं इस एसक्यूएल को समझाने के साथ चलाता हूं, तो मुझे ऐसा कुछ मिलता है: http://my.jetscreenshot.com/7536/20111225-myhj-41kb.jpg - क्या इन एनयूएलएल का मतलब है कि क्वेरी इंडेक्स का उपयोग नहीं कर रही है? इंडेक्स एक बीटीआरई है इसलिए मुझे लगता है कि इसे थोड़ा तेज चलाना चाहिए।

क्या आप कृपया इसके साथ मेरी मदद कर सकते हैं? अगर कोई अन्य सूचनाएं जरूरी हैं तो मुझे बताएं।

संपादित करें: मेरे पास suspects.postalcode, postal_codes.start, postal_codes.end, postal_codes.user_id पर अनुक्रमणिका है।

मैं मूल रूप से क्या हासिल करना कोशिश कर रहा हूँ: मैं, एक मेज, जहां प्रत्येक उपयोगकर्ता ID का कई का डाक कोड पर्वतमाला सौंपा गया है तो ऐसा लगता है कि:

user_id | start | end 

जहां प्रत्येक संदिग्ध है से मैं संदिग्धों की एक मेज है एक पता (जिसमें एक डाक कोड शामिल है), इसलिए इस क्वेरी में मैं डाक कोड प्राप्त करने की कोशिश कर रहा हूं - शुरुआत और अंत और इस श्रेणी में शहर का नाम भी।

उम्मीद है कि इससे मदद मिलती है।

+0

हाय जोसेफ, क्या आप प्रश्न को संपादित कर सकते हैं और प्रत्येक तालिका में मूल अनुक्रमणिका (एसएस) सूचीबद्ध कर सकते हैं जिसमें कॉलम (प्रत्येक) प्रत्येक में हैं और किस क्रम में? – TetonSig

+0

इसके अलावा, क्या आप यह स्पष्ट कर सकते हैं कि क्वेरी को वापस करने के लिए क्या माना जाता है? मुझे लगता है कि किसी दिए गए उपयोगकर्ता के लिए, आप किसी भी संदिग्ध डाक कोड से संबंधित शहर दिखाना चाहते हैं जो कि उस उपयोगकर्ता को सौंपी गई सीमा के भीतर आता है। और आप यह भी देखना चाहेंगे कि शहर किस श्रेणी में आता है। मैं पूछता हूं क्योंकि आप जो चाहते हैं उसे जानना हमें बताएगा कि क्वेरी को संरचित करने के लिए हमारे पास कौन से विकल्प हैं। – TetonSig

+0

हाय, मैंने पोस्ट संपादित कर लिया है, उम्मीद है कि अब एआरआर उपयोगी सूचनाएं हैं। – Joseph

उत्तर

0

यह केवल एक सूचकांक का उपयोग कर रहा है, न कि शामिल होने वाले क्षेत्रों के लिए। आरंभ और अंत क्षेत्रों के लिए एक सूचकांक बनाने, या का उपयोग कर> प्रयास करें = और < = के बजाय बीच

+0

नमस्ते, दोनों प्रारंभ और अंत फ़ील्ड अनुक्रमित हैं (खेद है कि मैंने इसका उल्लेख नहीं किया है), मैंने <= > = का प्रयास किया है लेकिन इसका एक ही परिणाम है। – Joseph

0

100 नहीं% यकीन है कि, लेकिन this प्रासंगिक हो सकता है:

Sometimes MySQL does not use an index, even if one is available. One circumstance under which this occurs is when the optimizer estimates that using the index would require MySQL to access a very large percentage of the rows in the table. (In this case, a table scan is likely to be much faster because it requires fewer seeks.) However, if such a query uses LIMIT to retrieve only some of the rows, MySQL uses an index anyway, because it can much more quickly find the few rows to return in the result.

तो LIMIT साथ परीक्षण की कोशिश, और अगर यह सूचकांक का उपयोग करता है, तो आपको अपना कारण मिला।

+0

हाय, मैंने 10 जैसे छोटे मूल्यों के साथ LIMIT जोड़ने की कोशिश की है और इसका कोई प्रभाव नहीं पड़ा:/ – Joseph

0

मुझे कहना है कि मैं आपके टेबल नामकरण सम्मेलन से थोड़ा उलझन में हूं, मैं उम्मीद करता हूं कि "संदिग्ध" तालिका में user_id postal_code नहीं होगा, लेकिन आपके पास आपके कारण होना चाहिए। यदि आप इस क्वेरी को छोड़ना चाहते हैं, तो आप पूर्ण तालिका स्कैन से बचने के लिए postal_code (स्टार, एंड) पर एक इंडेक्स जोड़ सकते हैं।

+0

हाय, postal_codes तालिका में 3 फ़ील्ड हैं: user_id, प्रारंभ करें, अंत करें ताकि यह मूल रूप से विभिन्न डाक कोड श्रेणियों के बारे में जानकारी रख सके निर्दिष्ट user_id के लिए। – Joseph

+0

"हाय, मेरे पास पहले से एक प्राथमिक कुंजी है जिसमें user_id, प्रारंभ, अंत" है। समस्या यह है कि MySQL केवल अनुक्रमणिका के उपसर्ग का उपयोग कर सकते हैं। उपयोगकर्ता आईडी उस खंड में नहीं है जहां आपकी अनुक्रमणिका का उपयोग नहीं किया जा रहा है। एक इंडेक्स होने का प्रयास करें जो शुरू होता है (प्रारंभ, अंत, ...)। –

+0

हाय, मैंने इंडेक्स जोड़े हैं, लेकिन फिर भी एक ही परिणाम। – Joseph

2

जब भी शामिल हो जाए तो पहली तालिका के सभी रिकॉर्ड इंडेक्स के आधार पर चयन के बजाय उठाए जाते हैं। मैं एक आंतरिक शामिल होने का सुझाव देना चाहूंगा। नीचे दी गई क्वेरी में कुछ पसंद है।

select distinct 
    s.city, 
    pc.start, 
    pc.end 
from postal_codes pc, suspect s 
where 
    s.postalcode between (select pc1.start, pc1.end from postal_code pc1 where pc1.user_id = "username") 
    and pc.user_id = "username" 
order by pc.start 
+0

आंतरिक शामिल आमतौर पर बाएं से धीमा होता है, और उप-प्रश्नों में चयन सूचकांक का उपयोग नहीं करते हैं। यूसुफ, क्या आपने कोशिश की है? – zapadlo

+0

धन्यवाद, यह मुझे एक त्रुटि देता है: ऑपरेंड में 1 कॉलम होना चाहिए, शायद मैं भाग के बीच में? मुझे यकीन नहीं है कि इसे कैसे लिखना है। – Joseph

0

मुझे लगता है कि आप निम्नलिखित की तरह आपकी क्वेरी गठित कर सकता है,

SELECT DISTINCT s.city, pc1.start, pc1.end FROM 
(SELECT pc.start and pc.end from postal_codes pc where pc.user_id = "username") as pc1, Suspect s 
WHERE s.postalcode BETWEEN pc1.start, pc1.end ORDER BY pc1.start 

आपकी क्वेरी रों मेज पर सूचकांक उठा नहीं है अपनी हालत के बीच की वजह से और बाएं में शामिल हो। आपकी तालिका में एक इंडेक्स होने का मतलब यह नहीं है कि इसका उपयोग सभी प्रश्नों में किया जाएगा।

+0

धन्यवाद, मैं आपकी क्वेरी का उपयोग किया है, लेकिन यह एक ही समय ले लिया:/ से अलग s.city, pc1.start, pc1.end का चयन करें (pc.start का चयन करें, postal_codes पीसी से pc.end कहां pc.user_id = pc1 के रूप में "उपयोगकर्ता नाम"), संदिग्धों रों कहां pc1.start और pc1.end आदेश के बीच s.postalcode द्वारा pc1.start – Joseph

+0

Joseph- समय क्वेरी का मूल्यांकन करने के भी क्या तालिका में डेटा वितरण है पर निर्भर हैं। – codemaster

+0

आपका क्या मतलब है? – Joseph

0

FORCE INDEX आज़माएं।

+0

हाय, उत्तर के लिए टैंक। मैंने संदिग्ध तालिका (डाक कोड फ़ील्ड) पर इंडेक्स को मजबूर कर दिया है लेकिन कोई प्रभाव नहीं, मैंने पोस्टक_codes तालिका पर प्रारंभ और अंत पर इंडेक्स को भी मजबूर करने की कोशिश की लेकिन क्वेरी में 5x अधिक लिया गया। – Joseph