Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर में इनर जॉइन बनाम लेफ्ट जॉइन परफॉर्मेंस

एक LEFT JOIN INNER JOIN . से बिल्कुल तेज़ नहीं है . वास्तव में, यह धीमा है; परिभाषा के अनुसार, एक बाहरी जुड़ाव (LEFT JOIN या RIGHT JOIN ) को INNER JOIN . का सारा काम करना होता है साथ ही परिणामों को अशक्त करने का अतिरिक्त कार्य। परिणाम सेट के बड़े आकार के कारण कुल निष्पादन समय को और बढ़ाते हुए, अधिक पंक्तियों को वापस करने की भी उम्मीद की जाएगी।

(और यहां तक ​​कि अगर कोई LEFT JOIN थे विशिष्ट . में तेज़ कारकों के कुछ मुश्किल-से-कल्पना संगम के कारण, यह कार्यात्मक रूप से INNER JOIN के बराबर नहीं है , इसलिए आप केवल एक के सभी इंस्टेंस को दूसरे के साथ बदलने के लिए नहीं जा सकते!)

सबसे अधिक संभावना है कि आपकी प्रदर्शन समस्याएं कहीं और हैं, जैसे उम्मीदवार कुंजी या विदेशी कुंजी ठीक से अनुक्रमित नहीं होना। 9 टेबल में शामिल होने के लिए काफी कुछ है इसलिए मंदी वस्तुतः लगभग कहीं भी हो सकती है। यदि आप अपना स्कीमा पोस्ट करते हैं, तो हम अधिक विवरण प्रदान करने में सक्षम हो सकते हैं।

संपादित करें:

इस पर और विचार करते हुए, मैं एक परिस्थिति के बारे में सोच सकता था जिसके तहत LEFT JOIN INNER JOIN . से तेज़ हो सकता है , और वह तब होता है जब:

  • कुछ टेबल बहुत हैं छोटा (कहते हैं, 10 पंक्तियों के नीचे);
  • तालिका में क्वेरी को कवर करने के लिए पर्याप्त अनुक्रमणिका नहीं है।

इस उदाहरण पर विचार करें:

CREATE TABLE #Test1
(
    ID int NOT NULL PRIMARY KEY,
    Name varchar(50) NOT NULL
)
INSERT #Test1 (ID, Name) VALUES (1, 'One')
INSERT #Test1 (ID, Name) VALUES (2, 'Two')
INSERT #Test1 (ID, Name) VALUES (3, 'Three')
INSERT #Test1 (ID, Name) VALUES (4, 'Four')
INSERT #Test1 (ID, Name) VALUES (5, 'Five')

CREATE TABLE #Test2
(
    ID int NOT NULL PRIMARY KEY,
    Name varchar(50) NOT NULL
)
INSERT #Test2 (ID, Name) VALUES (1, 'One')
INSERT #Test2 (ID, Name) VALUES (2, 'Two')
INSERT #Test2 (ID, Name) VALUES (3, 'Three')
INSERT #Test2 (ID, Name) VALUES (4, 'Four')
INSERT #Test2 (ID, Name) VALUES (5, 'Five')

SELECT *
FROM #Test1 t1
INNER JOIN #Test2 t2
ON t2.Name = t1.Name

SELECT *
FROM #Test1 t1
LEFT JOIN #Test2 t2
ON t2.Name = t1.Name

DROP TABLE #Test1
DROP TABLE #Test2

यदि आप इसे चलाते हैं और निष्पादन योजना देखते हैं, तो आप देखेंगे कि INNER JOIN क्वेरी वास्तव में LEFT JOIN से अधिक खर्च करती है , क्योंकि यह ऊपर दिए गए दो मानदंडों को पूरा करता है। ऐसा इसलिए है क्योंकि SQL सर्वर INNER JOIN . के लिए हैश मैच करना चाहता है , लेकिन LEFT JOIN . के लिए नेस्टेड लूप करता है; पूर्व सामान्य रूप से . है बहुत तेज़, लेकिन चूंकि पंक्तियों की संख्या इतनी कम है और उपयोग करने के लिए कोई अनुक्रमणिका नहीं है, हैशिंग ऑपरेशन क्वेरी का सबसे महंगा हिस्सा साबित होता है।

आप अपनी पसंदीदा प्रोग्रामिंग भाषा में एक प्रोग्राम लिखकर 5 तत्वों के साथ एक सूची में बड़ी संख्या में लुकअप करने के लिए एक ही प्रभाव देख सकते हैं, बनाम 5 तत्वों के साथ एक हैश तालिका। आकार के कारण, हैश तालिका संस्करण वास्तव में धीमा है। लेकिन इसे बढ़ाकर 50 तत्वों, या 5000 तत्वों तक करें, और सूची संस्करण क्रॉल में धीमा हो जाता है, क्योंकि यह हैशटेबल के लिए O(N) बनाम O(1) है।

लेकिन इस क्वेरी को ID . पर बदलने के लिए बदलें Name . के बजाय कॉलम और आप एक बहुत ही अलग कहानी देखेंगे। उस स्थिति में, यह दोनों प्रश्नों के लिए नेस्टेड लूप करता है, लेकिन INNER JOIN संस्करण क्लस्टर्ड इंडेक्स स्कैन में से किसी एक को खोज के साथ बदलने में सक्षम है - जिसका अर्थ है कि यह शाब्दिक रूप से परिमाण का क्रम होगा बड़ी संख्या में पंक्तियों के साथ तेज़।

तो निष्कर्ष कमोबेश वही है जो मैंने ऊपर कई पैराग्राफों का उल्लेख किया है; यह लगभग निश्चित रूप से एक अनुक्रमण या अनुक्रमणिका कवरेज समस्या है, संभवतः एक या अधिक बहुत छोटी तालिकाओं के साथ संयुक्त। केवल वे ही परिस्थितियाँ हैं जिनके तहत SQL सर्वर हो सकता है कभी-कभी INNER JOIN . के लिए बदतर निष्पादन योजना चुनें एक LEFT JOIN . की तुलना में ।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. CAST () का उपयोग करके SQL सर्वर में एक स्ट्रिंग को दिनांक/समय में कैसे परिवर्तित करें

  2. SQL सर्वर प्रबंधन स्टूडियो (SSMS) के साथ डेटाबेस डिज़ाइन सीखें - भाग 2

  3. टी-एसक्यूएल में मूल्यों की सूची में कॉलम की तुलना करना

  4. SQL प्रदर्शन:WHERE बनाम WHERE(ROW_NUMBER)

  5. सी # से SQL सर्वर को कॉल करते समय पुनः प्रयास करें या विफल होने के बारे में जानें?