sql - जॉइन का उपयोग करते समय क्लॉज बनाम कहां चालू करें




sql-server tsql (4)

मान लीजिए कि मेरे पास निम्न टी-एसक्यूएल कोड है:

SELECT * FROM Foo f
INNER JOIN Bar b ON b.BarId = f.BarId;
WHERE b.IsApproved = 1;

निम्नलिखित पंक्तियों का एक ही सेट भी लौटाता है:

SELECT * FROM Foo f
INNER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);

यह यहां सबसे अच्छा केस नमूना नहीं हो सकता है लेकिन क्या इन दोनों के बीच कोई प्रदर्शन अंतर है?


नहीं, क्वेरी ऑप्टिमाइज़र दोनों उदाहरणों के लिए एक ही निष्पादन योजना चुनने के लिए पर्याप्त स्मार्ट है।

आप निष्पादन योजना की जांच के लिए SHOWPLAN का उपयोग कर सकते हैं।

फिर भी, आपको ON क्लॉज और WHERE क्लॉज पर सभी प्रतिबंधों पर कनेक्शन में शामिल होना चाहिए।


बाहरी जुड़ने के साथ अंतर से सावधान रहें। एक प्रश्न जहां b.IsApproved का एक फ़िल्टर b.IsApproved (दाएं टेबल पर, बार) JOIN की ON स्थिति में जोड़ा जाता है:

SELECT * 
FROM Foo f 
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId); 

WHERE खंड में फ़िल्टर रखने के समान नहीं है:

SELECT * 
FROM Foo f 
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1); 

चूंकि 'असफल' Bar शामिल हो जाता है (यानी जहां b.BarId लिए कोई b.BarId नहीं है), यह b.IsApproved को छोड़ b.IsApproved ऐसी सभी असफल पंक्तियों के लिए b.IsApproved रूप में b.IsApproved , और इन पंक्तियों को तब फ़िल्टर किया जाएगा।

इस पर ध्यान देने का एक और तरीका यह है कि पहली पूछताछ के लिए, LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId) हमेशा बाएं टेबल पंक्तियों को वापस कर देगा, क्योंकि LEFT OUTER JOIN गारंटी देता है अगर असफल हो जाता है तब भी बाएं टेबल पंक्तियां वापस कर दी जाएंगी। हालांकि, शर्त पर LEFT OUTER JOIN में जोड़ने के लिए (b.IsApproved = 1) का प्रभाव किसी भी सही तालिका कॉलम को बाहर करना है जब (b.IsApproved = 1) गलत है, यानी सामान्य रूप से LEFT JOIN से लागू नियमों के अनुसार LEFT JOIN हालत (b.BarId = f.BarId)(b.BarId = f.BarId)(b.BarId = f.BarId)

अद्यतन : कॉनराड द्वारा पूछे गए प्रश्न को पूरा करने के लिए, एक वैकल्पिक फ़िल्टर के लिए समकक्ष LOJ होगा:

SELECT * 
FROM Foo f 
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);

यानी WHERE क्लॉज को दोनों स्थितियों पर विचार करने की आवश्यकता है कि क्या शामिल हो जाता है (NULL) और फ़िल्टर को अनदेखा किया जाना है, और जहां शामिल हो जाता है और फ़िल्टर लागू होना चाहिए। ( b.IsApproved या b.BarId को b.BarId लिए परीक्षण किया जा सकता NULL )

मैंने यहां एक एसकफ्लिडल एक साथ रखा है जो बीआई के विभिन्न प्लेसमेंट के बीच अंतर दर्शाता है। b.IsApproved सापेक्ष b.IsApproved फ़िल्टर।


मैंने अभी चार टेबलों के खिलाफ एक प्रश्न का परीक्षण किया - तीन इंटर्न जॉइन और कुल चार पैरामीटर वाले एक प्राथमिक तालिका, और दोनों दृष्टिकोणों की निष्पादन योजनाओं की तुलना की (जॉइन के ऑन में फ़िल्टर मानदंडों का उपयोग करके, और फिर भी WHERE खंड)।

निष्पादन योजना बिल्कुल वही हैं। मैंने इसे SQL Server 2008 R2 पर चलाया।


SELECT * FROM Foo f
INNER JOIN Bar b ON b.BarId = f.BarId
WHERE b.IsApproved = 1;

यह जाने के लिए बेहतर रूप है। इसे पढ़ने और संशोधित करने में आसान है। व्यापारिक दुनिया में यही वह है जिसे आप साथ जाना चाहते हैं। जहां तक ​​प्रदर्शन वे वही हैं।





inner-join