2011-09-08 16 views
5

मुझे पता चला कि कुछ मामलों मेंएसक्यूएल सर्वर बनाम सबक्वेरी प्रदर्शन प्रश्न में शामिल होने

select 
    usertable.userid, 
    (select top 1 name from nametable where userid = usertable.userid) as name 
from usertable 
where active = 1 

की तरह एक प्रश्न

select 
    usertable.userid, 
    nametable.name 
from usertable 
left join nametable on nametable.userid = usertable.userid 
where usertable.active = 1 

जहां दोनों बराबर की तुलना में SS2008R2 में पूरा करने के लिए क्वेरी में शामिल होने के लंबे समय तक परिमाण के एक आदेश ले जाता है टेबल अनुक्रमित हैं और 100k पंक्तियों से अधिक है। दिलचस्प बात यह है मूल प्रश्न में एक शीर्ष खंड डालने इसमें शामिल होने क्वेरी के साथ बराबरी पर प्रदर्शन बनाता है:

select 
    top (select count(*) from usertable where active = 1) usertable.userid, 
    (select top 1 name from nametable where userid = usertable.userid) as name 
from usertable 
where active = 1 

किसी को भी किसी भी विचार क्यों मूल प्रश्न तो खराब प्रदर्शन है?

+3

FYI करें जब प्रदर्शन की समस्याओं के निदान के लिए आप हमेशा एक प्रश्न कार्य योजना लागू करके मिलना चाहिए। – Justin

+0

यदि आपके पास सफारी पुस्तकें ऑनलाइन तक पहुंच है तो "माइक्रोसॉफ्ट® एसक्यूएल सर्वर 2005 के अंदर: क्वेरी ट्यूनिंग और ऑप्टिमाइज़ेशन - अध्याय 3" या एक और अच्छा लिंक http://blogs.msdn.com/b/craigfr/archive/2006 पर एक नज़र डालें /09/27/774107.aspx –

उत्तर

3

ठीक है, प्रश्न अलग हैं - जब तक userid कॉलम प्राथमिक कुंजी नहीं है या विशिष्टता बाधा है तो दूसरी क्वेरी पहले की तुलना में अधिक पंक्तियां वापस कर सकती है।

जिसके अनुसार, इस धारणा के साथ कि userid एक प्राथमिक कुंजी/अद्वितीय पहले सबक्वेरी के TOP 1 हिस्से को हटाने की कोशिश है:

select 
    usertable.userid, 
    (select name from nametable where userid = usertable.userid) as name 
from usertable 
where active = 1 
+0

वह पूरी तरह से चाल है। फ्लाई पर क्वेरी उत्पन्न होने के बाद से रनटाइम त्रुटियों से बचने के लिए मुझे सावधानी बरतनी थी। अब मुझे यह पता लगाने की ज़रूरत है कि क्या मैं इसे सामान्य नियम के रूप में सुरक्षित रूप से हटा सकता हूं। –

2

यह एक सहसंबद्ध सबक्वेरी है, जो इसे यह बाहरी क्वेरी में एक क्षेत्र का संदर्भ के बाद से बाहरी क्वेरी की वापसी प्रति पंक्ति एक बार निष्पादित करने के लिए की जरूरत है इसका मतलब है।

एक JOIN रन एक बार पूरे परिणाम के लिए निर्धारित किया है और विलय कर दिया जाता है। आपकी सबक्वायरी बाहरी क्वेरी चलाती है, फिर प्रत्येक लौटाई गई पंक्ति के लिए यह सबक्वायरी फिर से चलाती है।

+1

मुझे नहीं लगता कि यह SQL सर्वर के साथ सच है। – JeffO

+2

@ जेफ - तो आप गलत हैं। – JNK

1

मूल प्रश्न उप select रूप में कई बार के रूप में वहाँ, पंक्तियों हैं, इस प्रकार खराब प्रदर्शन पर अमल होगा।

जब आप JOIN आप पूरे परिणाम में एक बार सेट मिलता है।