2012-01-25 17 views
5

से बहुत धीमी है, मैं इस बेहद अजीब स्थिति में आया, और मैंने सोचा कि मैं इसे खोजने के लिए भीड़ को फेंक दूंगा।कनेक्टेड सर्वर टेबल पर INNER जॉइन उप-क्वेरी

मैं एक प्रश्न है कि किसी लिंक किए गए सर्वर पर एक टेबल में शामिल होने गया था:

select a.*, b.phone 
from table_a a, 
join remote.table_b b on b.id = a.id 
(lots of data on A, but very few on B) 

इस क्वेरी हमेशा के लिए बात कर रहा था (कभी भी वास्तविक रन टाइम में पता चला), और वह यह है कि जब मैं B नहीं था देखा सूचकांक, इसलिए मैंने इसे जोड़ा, लेकिन इससे इस मुद्दे को ठीक नहीं किया गया। अंत में, हताशा में मैंने कोशिश की:

select a.*, b.phone 
from table_a a, 
join (select id, phone from remote.B) as b on b.id = a.id 

क्वेरी के इस संस्करण में, मेरे मन में कम से कम के रूप में, एक ही परिणाम होना चाहिए, लेकिन लो और निहारना, इसके तुरंत जवाब!

कोई विचार क्यों कोई लटकाएगा और दूसरी प्रक्रिया जल्दी से? और हाँ, मैंने यह सुनिश्चित करने के लिए इंतजार किया था कि इंडेक्स दोनों को चलाने से पहले बनाया गया था।

+0

क्या आपने दोनों के लिए निष्पादन योजना देखी है? क्या वे अलग हैं? क्या आपने प्रत्येक विधि के बीच _dbcc dropcleanbuffers_ जारी किया था? – canon

+0

'रिमोट.बी' में कितने रिकॉर्ड हैं? – Yuck

+0

"रिमोट" डीबी एक लिंक सर्वर के माध्यम से पहुंचे किसी अन्य सर्वर पर है और लगभग 600 पंक्तियां हैं। – Limey

उत्तर

4

यह क्योंकि कभी-कभी (अक्सर) निष्पादन स्वचालित रूप से द्वारा उत्पन्न योजना है में हर पंक्ति के लिए जुड़ा हुआ सर्वर से inner loop join गोल यात्रा कर सकते हैं एसक्यूएल सर्वर इंजन उतना अच्छा और स्पष्ट नहीं है जितना हम चाहते हैं। आप दोनों परिस्थितियों में निष्पादन योजना देख सकते हैं। मैं पहली क्वेरी में संकेत का उपयोग करने का सुझाव देता हूं, ऐसा कुछ: इनर मेर्ज जॉइन।

यहाँ इस बारे में कुछ और जानकारी है:

http://msdn.microsoft.com/en-us/library/ms181714.aspx

+0

यह एक अच्छी नई बात है जिसे मैंने आज सीखा है! मैं कुछ अन्य स्थानों को जानता हूं जो मैं इस तरह के विलय का उपयोग कर सकता हूं। – Limey

+0

मैं दृश्य में शामिल होने के लिए मर्ज संकेत का उपयोग कर रहा हूं (3 टेबल से बनाया गया) और तालिका। देखें पहले से ही निष्पादन योजना है लेकिन यहां तक ​​कि इंजन भी नया, बहुत धीमा बनाता है। यह एक और मामला है जब आप इसे उपयोगी पा सकते हैं। – devarc

+3

'मेर्ज' जादू नहीं है "तेजी से जाओ" संकेत। यदि आपको सही योजना नहीं मिल रही है तो पहले समझना बेहतर है कि क्यों। बेशक –

1

रिमोट टेबल उस सर्वर पर नहीं है? क्या यह संभव है कि जॉइन वास्तव में रिमोट टेबल पर एकाधिक कॉल कर रहा हो, जबकि सबक्वायरी टेबल डेटा की प्रतिलिपि के लिए एक ही अनुरोध कर रही है, जिसके परिणामस्वरूप नेटवर्क पर कम समय इंतजार हो रहा है?

+0

'~ 600' पंक्तियों पर संदर्भित नहीं किया गया है। इस विचार का समर्थन करने के लिए कुछ ढूंढें कि सबक्वायरी के परिणामस्वरूप पूरी तालिका कैश की जा रही है और यह मेरा +1 – Yuck

+0

प्राप्त करता है अनुमानित निष्पादन योजना से पता चलता है कि यह केवल क्वेरी के दोनों संस्करणों में इसे एक बार एक्सेस कर रहा है। खराब प्रसंस्करण का 40% उपयोग करके अनुमान लगाया जाता है, जबकि दूसरा एक 1% – Limey

+0

लाइमी है, निष्पादन योजना में सटीक शब्द क्या है? मुझे आश्चर्य होगा अगर यह वास्तव में प्रक्रियाओं के लिए आंतरिक कॉल किए गए कॉल की संख्या इंगित करता है। –

3

जुड़ा हुआ सर्वर के लिए 2 संस्करण सभी डेटा स्थानीय रूप से prefetches और शामिल होने के करते हैं, क्योंकि 1 संस्करण एक

+0

@ पहली संस्करण के लिए लाइमी ** ** दूरस्थ कॉल के लिए प्रश्न योजना में निष्पादन की संख्या ** - यदि यह 1 से अधिक है- तो यह ** ** –

+0

के लिए roundtripd अनुमानित निष्पादन योजना की जांच की गई है; उस तालिका के लिए कोई आंतरिक लूप शामिल नहीं हो रहा है। – Limey

+1

@Liney - दूरस्थ तालिका आइटम के लिए ** निष्पादन की संख्या ** क्या है? या हमें पूरी क्वेरी योजना को XML –

1

मैं बस यहाँ एक अनुमान के लिए जा रहा हूँ। जब आप remote.b तक पहुंचते हैं तो यह किसी अन्य सर्वर पर एक टेबल है?

यदि ऐसा है, तो दूसरी क्वेरी तेज़ी से कारण है क्योंकि, आप अन्य सर्वर से एक प्रश्न पूछते हैं और डेटा को प्रोसेस करने से पहले बी से आपको आवश्यक सभी फ़ील्ड प्राप्त करते हैं। पहली क्वेरी में आप डेटा प्रोसेस कर रहे हैं और साथ ही आप दूसरे सर्वर पर कई अनुरोध कर रहे हैं।

आशा है कि यह आपकी मदद करेगा।