SQL सर्वर में INNER JOIN LEFT JOIN परफॉर्मेंस


259

मैंने SQL कमांड बनाया है जो 9 टेबल पर INNER JOIN का उपयोग करता है, वैसे भी यह कमांड बहुत लंबा समय (पांच मिनट से अधिक) लेता है। इसलिए मेरे लोक ने मुझे INNER JOIN को LEFT JOIN में बदलने का सुझाव दिया क्योंकि LEFT JOIN का प्रदर्शन मेरे जानने के बावजूद बेहतर है। मैंने इसे बदलने के बाद, क्वेरी की गति में काफी सुधार किया।

मैं जानना चाहता हूं कि क्यों INNER JOIN की तुलना में LEFT JOIN तेज है?

मेरा एसक्यूएल कमांड नीचे जैसा दिखता है: SELECT * FROM A INNER JOIN B ON ... INNER JOIN C ON ... INNER JOIN Dऔर इसी तरह

अद्यतन: यह मेरे स्कीमा का संक्षिप्त विवरण है।

FROM sidisaleshdrmly a -- NOT HAVE PK AND FK
    INNER JOIN sidisalesdetmly b -- THIS TABLE ALSO HAVE NO PK AND FK
        ON a.CompanyCd = b.CompanyCd 
           AND a.SPRNo = b.SPRNo 
           AND a.SuffixNo = b.SuffixNo 
           AND a.dnno = b.dnno
    INNER JOIN exFSlipDet h -- PK = CompanyCd, FSlipNo, FSlipSuffix, FSlipLine
        ON a.CompanyCd = h.CompanyCd
           AND a.sprno = h.AcctSPRNo
    INNER JOIN exFSlipHdr c -- PK = CompanyCd, FSlipNo, FSlipSuffix
        ON c.CompanyCd = h.CompanyCd
           AND c.FSlipNo = h.FSlipNo 
           AND c.FSlipSuffix = h.FSlipSuffix 
    INNER JOIN coMappingExpParty d -- NO PK AND FK
        ON c.CompanyCd = d.CompanyCd
           AND c.CountryCd = d.CountryCd 
    INNER JOIN coProduct e -- PK = CompanyCd, ProductSalesCd
        ON b.CompanyCd = e.CompanyCd
           AND b.ProductSalesCd = e.ProductSalesCd 
    LEFT JOIN coUOM i -- PK = UOMId
        ON h.UOMId = i.UOMId 
    INNER JOIN coProductOldInformation j -- PK = CompanyCd, BFStatus, SpecCd
        ON a.CompanyCd = j.CompanyCd
            AND b.BFStatus = j.BFStatus
            AND b.ProductSalesCd = j.ProductSalesCd
    INNER JOIN coProductGroup1 g1 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup1Cd
        ON e.ProductGroup1Cd  = g1.ProductGroup1Cd
    INNER JOIN coProductGroup2 g2 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup2Cd
        ON e.ProductGroup1Cd  = g2.ProductGroup1Cd

1
क्या आप किसी विशेषता को प्रोजेक्ट करते हैं coUOM? यदि नहीं तो आप सेमी जॉइन का उपयोग करने में सक्षम हो सकते हैं। यदि हाँ, तो आप UNIONएक विकल्प के रूप में उपयोग करने में सक्षम होंगे । सिर्फ आपका FROMक्लॉज पोस्ट करना यहां अपर्याप्त जानकारी है।
onedaywhen

1
मैंने ऐसा बार-बार सोचा है (क्योंकि मैं हर समय देखता हूं)।
पॉल ड्रेपर

1
क्या आपने अपने संक्षिप्त स्कीमा में एक आदेश याद किया? मैंने अभी हाल ही में एक समस्या का सामना किया है, जहाँ एक इनवॉयर जॉइन को LEFT OUTER JOIN में बदलना 3 मिनट से 10 सेकंड तक क्वेरी को गति देता है। यदि आपके पास वास्तव में आपकी क्वेरी में ऑर्डर बाय है, तो मैं आगे एक उत्तर के रूप में समझाऊंगा। ऐसा लगता है कि सभी उत्तर वास्तव में उस मामले की व्याख्या नहीं करते हैं जिसका मैंने सामना किया था।
फुआ ये केट

जवाबों:


403

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 तत्वों तक बढ़ाएं, और सूची संस्करण क्रॉल में धीमा हो जाता है, क्योंकि यह हैशटेबल के लिए ओ (एन) बनाम ओ (1) है।

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

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


4
एक और परिदृश्य है जो एक INNER JOIN से बेहतर प्रदर्शन करने वाले OUTER JOIN का कारण बन सकता है। नीचे मेरा जवाब देखें।
डेबनहम

12
मैं यह बताना चाहता हूं कि इस विचार का समर्थन करने के लिए मूल रूप से कोई डेटाबेस प्रलेखन नहीं है कि आंतरिक जुड़ाव और बाहरी प्रदर्शन अलग-अलग जुड़ते हैं। आँकड़ों के आयतन और परिणाम सेट के आकार की वजह से बाहरी जोड़ आंतरिक जोड़ की तुलना में थोड़े महंगे होते हैं। हालाँकि, अंतर्निहित एल्गोरिदम ( msdn.microsoft.com/en-us/library/ms191426(v=sql.105).aspx ) दोनों प्रकार के जोड़ों के लिए समान हैं। जब वे डेटा की समान मात्रा वापस करते हैं तो प्रदर्शन समान होना चाहिए।
गॉर्डन लिनॉफ़

3
@Aaronaught। । । इस उत्तर को एक टिप्पणी में संदर्भित किया गया था, जिसने इस आशय के बारे में कुछ कहा था कि "बाहरी जुड़ाव आंतरिक जोड़ की तुलना में काफी खराब प्रदर्शन करते हैं"। मैंने सिर्फ यह सुनिश्चित करने के लिए टिप्पणी की कि यह गलत व्याख्या नहीं फैलेगी।
गॉर्डन लाइनऑफ़

16
मुझे लगता है कि यह उत्तर एक महत्वपूर्ण पहलू में भ्रामक है: क्योंकि इसमें कहा गया है कि "एक वामपंथी जिन्न इनर जॉय की तुलना में बिल्कुल तेज नहीं है"। यह लाइन सही नहीं है। यह सैद्धांतिक रूप से INNER JOIN से तेज नहीं है। यह है नहीं "बिल्कुल नहीं तेजी से।" सवाल विशेष रूप से एक प्रदर्शन सवाल है। व्यवहार में मैंने अब कुछ सिस्टम (बहुत बड़ी कंपनियों द्वारा!) देखा है, जहां INNER JOIN, OUTER JOIN की तुलना में हास्यास्पद रूप से धीमा था। सिद्धांत और व्यवहार बहुत अलग चीजें हैं।
डेविड फ्रेनकेल

5
@DavidFrenkel: यह अत्यधिक संभावना नहीं है। यदि आप मानते हैं कि इस तरह की विसंगति संभव है, तो मैं निष्पादन योजनाओं के साथ ए / बी तुलना देखने के लिए कहूंगा। संभवतः यह कैश्ड क्वेरी / निष्पादन योजनाओं, या खराब आँकड़ों से संबंधित है।
आरोही

127

एक महत्वपूर्ण परिदृश्य है कि एक बाहरी जुड़ाव एक आंतरिक जुड़ाव से तेज हो सकता है जो अभी तक चर्चा नहीं की गई है।

बाहरी जुड़ने का उपयोग करते समय, ऑप्टिमाइज़र निष्पादन योजना से बाहरी जुड़ने वाली तालिका को छोड़ने के लिए हमेशा स्वतंत्र होता है यदि जुड़ने वाले स्तंभ बाहरी तालिका के पीके होते हैं, और बाहरी तालिका के बाहरी स्तंभों में से कोई भी स्वयं सम्मिलित नहीं होता है। उदाहरण के लिएSELECT A.* FROM A LEFT OUTER JOIN B ON A.KEY=B.KEY और B.KEY B. के लिए पीके है। दोनों ओरेकल (मेरा मानना ​​है कि मैं रिलीज 10 का उपयोग कर रहा था) और एसक्यूएल सर्वर (मैंने 2008 R2 का इस्तेमाल किया) प्रुन टेबल बी को निष्पादन योजना से।

आंतरिक रूप से जुड़ने के लिए समान रूप से सही नहीं है: SELECT A.* FROM A INNER JOIN B ON A.KEY=B.KEYनिष्पादन की योजना में बी की आवश्यकता हो सकती है या नहीं, इस पर निर्भर करता है कि क्या बाधाएं मौजूद हैं।

यदि A.KEY एक अशक्त विदेशी कुंजी है जो B.KEY का उल्लेख करता है, तो अनुकूलक बी को योजना से नहीं हटा सकता क्योंकि यह पुष्टि करनी चाहिए कि प्रत्येक A पंक्ति के लिए B पंक्ति मौजूद है।

यदि A.KEY एक अनिवार्य विदेशी कुंजी है। B.KEY, तो ऑप्टिमाइज़र B को योजना से छोड़ने के लिए स्वतंत्र है क्योंकि बाधाएं पंक्ति के अस्तित्व की गारंटी देती हैं। लेकिन सिर्फ इसलिए कि अनुकूलक योजना से तालिका को गिरा सकता है, इसका मतलब यह नहीं होगा। SQL Server 2008 R2 योजना से B को नहीं छोड़ता है। ओरेकल 10 योजना से बी को छोड़ देता है। यह देखना आसान है कि इस मामले में बाहरी सर्वर SQL सर्वर पर आंतरिक रूप से शामिल कैसे होगा।

यह एक तुच्छ उदाहरण है, और एक स्टैंड-अलोन क्वेरी के लिए व्यावहारिक नहीं है। अगर आपको जरूरत नहीं है तो एक टेबल से क्यों जुड़ें?

लेकिन विचारों को डिजाइन करते समय यह एक बहुत ही महत्वपूर्ण डिजाइन विचार हो सकता है। अक्सर एक "डू-एवरीथिंग" दृश्य बनाया जाता है जो एक उपयोगकर्ता को एक केंद्रीय तालिका से संबंधित आवश्यकता हो सकती है सब कुछ में शामिल होता है। (विशेष रूप से अगर ऐसे भोले उपयोगकर्ता हैं जो तदर्थ प्रश्नों को समझते हैं जो संबंधपरक मॉडल को नहीं समझते हैं) तो दृश्य में कई तालिकाओं से सभी रीलेवेंट कॉलम शामिल हो सकते हैं। लेकिन अंतिम उपयोगकर्ता केवल दृश्य के भीतर तालिकाओं के सबसेट से स्तंभों तक पहुंच सकते हैं। यदि तालिकाओं को बाहरी जोड़ के साथ जोड़ा जाता है, तो अनुकूलक योजना से गैर-आवश्यक तालिकाओं को छोड़ सकता है (और करता है)।

यह सुनिश्चित करना महत्वपूर्ण है कि बाहरी जोड़ का उपयोग करने वाला दृश्य सही परिणाम देता है। जैसा कि आरोनियट ने कहा है - आप INNER JOIN के लिए OUTER JOIN को नेत्रहीन रूप से स्थान नहीं दे सकते हैं और उसी परिणाम की अपेक्षा कर सकते हैं। लेकिन ऐसे समय होते हैं जब विचारों का उपयोग करते समय प्रदर्शन कारणों से यह उपयोगी हो सकता है।

एक अंतिम नोट - मैंने ऊपर के प्रकाश में प्रदर्शन पर प्रभाव का परीक्षण नहीं किया है, लेकिन सिद्धांत रूप में ऐसा लगता है कि आपको सुरक्षित रूप से एक INNER JOIN को OUTER JOIN से बदलने में सक्षम होना चाहिए यदि आप भी शर्त जोड़ते हैं <FOREIGN_KEY> IS पूर्ण नहीं है जहां खंड के लिए।


5
मैं वास्तव में इस समस्या में भाग गया जब अत्यंत गतिशील प्रश्नों का निर्माण। मैंने एक INNER JOIN में छोड़ दिया था जिसका मैं उपयोग कर रहा था और उससे डेटा नहीं खींच रहा था, और जब मैंने इसे एक LEFT JOIN (कतरनी जिज्ञासा से बाहर) में स्विच किया तो वास्तव में क्वेरी तेजी से चली।
एरिक फिलिप्स

1
EDIT - निष्पादन की योजना से बाहरी सम्मिलित तालिका को छोड़ने के लिए ऑप्टिमाइज़र के लिए मौजूद होने वाली शर्तों को स्पष्ट किया।
डेबानहम

2
आपके उत्तर के लिए एक छोटा स्पष्टीकरण: जब विदेशी कुंजी कॉलम गैर-अशक्त होता है, तो INNER JOIN और LEFT JOIN शब्दार्थ के बराबर हो जाते हैं (यानी आपका सुझाया गया WHERE क्लॉज निरर्थक है); एकमात्र अंतर निष्पादन योजना होगी।
डगलस

2
हालांकि यह वास्तव में एक तुच्छ उदाहरण दिखाता है, यह एक असाधारण रूप से व्यावहारिक जवाब है!
पबलगा

6
+1: मुझे लगता है कि इसमें कुछ प्रश्नों पर भाग लिया गया है जहां मैं कुछ बहुत बड़ी तालिकाओं के साथ आंतरिक जोड़ का उपयोग कर रहा था। भीतर का जुड़ाव क्वेरी प्लान में टेम्पीडब में एक स्पिल पैदा कर रहा था (मैं ऊपर बताए गए कारण के लिए मान रहा हूं - और मेरे सर्वर में मेमोरी में सब कुछ रखने के लिए रैम की कमी है)। लेफ्ट जॉइन पर स्विच करने से टेम्पर्ड बीपीएल समाप्त हो गया, जिसके परिणामस्वरूप मेरे 20-30 सेकंड के कुछ प्रश्न अब एक सेकंड के अंशों में चलते हैं। यह एक बहुत ही महत्वपूर्ण गोटा है जिसे देखकर अधिकांश लोग कंबल की धारणा बनाने लगते हैं कि आंतरिक जुड़ाव तेजी से होता है।
phosplait

23

अगर सब कुछ काम करता है जैसा कि इसे नहीं होना चाहिए, लेकिन हम सभी जानते हैं कि सब कुछ काम नहीं करता है, खासकर जब यह क्वेरी ऑप्टिमाइज़र, क्वेरी प्लान कैशिंग और आंकड़ों की बात आती है।

पहले मैं सूचकांक और आंकड़ों के पुनर्निर्माण का सुझाव दूंगा, फिर क्वेरी प्लान कैश को केवल यह सुनिश्चित करने के लिए कि चीजों को खराब नहीं करना है। हालाँकि मैंने समस्याओं का सामना किया है, तब भी।

मैंने कुछ ऐसे मामलों का अनुभव किया है, जहाँ एक लेफ्ट जॉइन एक इनर जॉइन की तुलना में तेज़ हुआ है।

अंतर्निहित कारण यह है: यदि आपके पास दो टेबल हैं और आप एक इंडेक्स (दोनों टेबलों पर) वाले कॉलम पर जुड़ते हैं। यदि आप तालिका एक पर सूचकांक में प्रविष्टियों पर लूप करते हैं और तालिका दो पर सूचकांक के साथ मिलान करते हैं तो आंतरिक परिणाम समान रूप से कोई फर्क नहीं पड़ता है, जैसे कि आप रिवर्स करेंगे: तालिका दो पर सूचकांक में प्रविष्टियों पर लूप करें और सूचकांक के साथ मिलान करें तालिका एक में। समस्या तब होती है जब आपके पास भ्रामक आँकड़े होते हैं, क्वेरी ऑप्टिमाइज़र कम से कम मिलान वाली प्रविष्टियों (आपके अन्य मानदंडों के आधार पर) के साथ तालिका खोजने के लिए सूचकांक के आँकड़ों का उपयोग करेगा। यदि आपके पास प्रत्येक में 1 मिलियन के साथ दो टेबल हैं, तो एक में आपकी 10 पंक्तियाँ मेल खाती हैं और तालिका दो में आपकी 100000 पंक्तियाँ मेल खाती हैं। सबसे अच्छा तरीका यह होगा कि तालिका एक पर एक सूचकांक स्कैन किया जाए और तालिका दो में 10 बार मिलान किया जाए। रिवर्स एक इंडेक्स स्कैन होगा जो 100000 पंक्तियों पर लूप करता है और 100000 बार और केवल 10 सफल होने की कोशिश करता है। इसलिए यदि आंकड़े सही नहीं हैं, तो आशावादी गलत तालिका और सूचकांक को लूप ओवर करने के लिए चुन सकता है।

यदि ऑप्टिमाइज़र बाईं ओर के आर्डर को ऑप्टिमाइज़ करने का आदेश देता है तो यह लिखा जाता है कि यह इनर जॉइन से बेहतर प्रदर्शन करेगा।

लेकिन, ऑप्टिमाइज़र लेफ्ट सेमी-ज्वाइनिंग के तौर पर ले-अप को भी ऑप्टिमाइज़ कर सकता है। इसे चुनने के लिए जिसे आप चाहते हैं वह बल आदेश संकेत का उपयोग कर सकता है।


18

OPTION (FORCE ORDER)समाप्ति के साथ और परिणाम पोस्ट करने के लिए दोनों क्वेरी (आंतरिक और बाईं ओर के साथ एक) का प्रयास करें ।OPTION (FORCE ORDER)एक क्वेरी संकेत है जो ऑप्टिमाइज़र को क्वेरी में दिए गए सम्मिलित आदेश के साथ निष्पादन योजना बनाने के लिए मजबूर करता है।

यदि INNER JOINउतनी ही तेजी से प्रदर्शन शुरू होता है LEFT JOIN, तो यह है क्योंकि:

  • पूरी तरह से एक क्वेरी में INNER JOIN s , जुड़ने का क्रम मायने नहीं रखता है। यह क्वेरी ऑप्टिमाइज़र को जुड़ने का आदेश देता है क्योंकि यह फिट दिखता है, इसलिए समस्या ऑप्टिमाइज़र पर निर्भर हो सकती है।
  • इसके साथ LEFT JOIN, ऐसा नहीं है क्योंकि ज्वाइन ऑर्डर बदलने से क्वेरी के परिणाम बदल जाएंगे। इसका मतलब है कि इंजन को आपके द्वारा क्वेरी पर दिए गए ज्वाइन ऑर्डर का पालन करना चाहिए, जो कि अनुकूलित से बेहतर हो सकता है।

पता नहीं कि यह आपके प्रश्न का उत्तर देता है, लेकिन मैं एक बार एक ऐसी परियोजना में था जिसने गणना करने वाले अत्यधिक जटिल प्रश्नों को चित्रित किया था, जिसने आशावादी को पूरी तरह से गड़बड़ कर दिया था। हमारे पास ऐसे मामले थे FORCE ORDERजो किसी क्वेरी के निष्पादन समय को 5 मिनट से 10 सेकंड तक कम कर देंगे।


9

बाएं बाहरी और आंतरिक जोड़ के बीच कई तुलनाएं की हैं और एक अंतर अंतर को खोजने में सक्षम नहीं हैं। कई चर हैं। एक रिपोर्टिंग डेटाबेस पर हजारों तालिकाओं के साथ बड़ी संख्या में फ़ील्ड्स के साथ काम करना, समय के साथ कई बदलाव (विक्रेता संस्करण और स्थानीय वर्कफ़्लो)। इस तरह के विस्तृत प्रश्नों की जरूरतों को पूरा करने और ऐतिहासिक डेटा को संभालने के लिए सभी इंडेक्सिंग कवरिंग इंडेक्स बनाना संभव नहीं है। आंतरिक प्रश्नों को सर्वर के प्रदर्शन को मारते देखा है क्योंकि दो बड़ी (लाखों से दसियों लाख पंक्तियाँ) तालिकाएँ बड़ी संख्या में फ़ील्ड को खींचने और दोनों को कवर करने वाले इंडेक्स मौजूद नहीं हैं।

हालांकि सबसे बड़ा मुद्दा, ऊपर की चर्चाओं में प्रकट नहीं होता है। हो सकता है कि आपका डेटाबेस अच्छी तरह से डेटा सुनिश्चित करने के लिए ट्रिगर्स और अच्छी तरह से डिज़ाइन किए गए लेनदेन प्रसंस्करण के साथ डिज़ाइन किया गया हो। मेरा अक्सर NULL मान होता है जहाँ वे अपेक्षित नहीं हैं। हां, टेबल की परिभाषाएं नो-नल्स लागू कर सकती हैं, लेकिन यह मेरे वातावरण में एक विकल्प नहीं है।

तो सवाल यह है कि ... क्या आप अपनी क्वेरी को केवल गति के लिए डिज़ाइन करते हैं, लेन-देन प्रसंस्करण के लिए एक उच्च प्राथमिकता जो एक ही कोड को एक मिनट में हजारों बार चलाता है। या आप सटीकता के लिए जाते हैं जो एक बाएं बाहरी जुड़ाव प्रदान करेगा। याद रखें कि आंतरिक जुड़ावों को दोनों तरफ मैच मिलना चाहिए, इसलिए एक अनपेक्षित NULL न केवल दो तालिकाओं बल्कि संभवतः सूचनाओं की पूरी पंक्तियों से डेटा हटा देगा। और यह इतनी अच्छी तरह से होता है, कोई त्रुटि संदेश नहीं।

आप आवश्यक डेटा का 90% प्राप्त करने के लिए बहुत तेज़ हो सकते हैं और पता नहीं लगा सकते हैं कि आंतरिक जुड़ावों ने चुपचाप हटा दी गई जानकारी है। कभी-कभी आंतरिक जोड़ तेजी से हो सकते हैं, लेकिन मुझे विश्वास नहीं है कि जब तक वे निष्पादन योजना की समीक्षा नहीं करते हैं, तब तक कोई भी उस धारणा को नहीं बनाता है। गति महत्वपूर्ण है, लेकिन सटीकता अधिक महत्वपूर्ण है।


8

आपके प्रदर्शन की समस्याएँ आपके द्वारा किए जा रहे जोड़ की संख्या के कारण होने की अधिक संभावना है और आप जिन स्तंभों पर शामिल हो रहे हैं उनमें अनुक्रमणिका हैं या नहीं।

सबसे खराब स्थिति यह है कि आप आसानी से प्रत्येक जॉइन के लिए 9 पूरे टेबल स्कैन कर सकते हैं।


7

जब विचारों में उपयोग किया जाता है तो बाहरी जोड़ बेहतर प्रदर्शन दे सकते हैं।

मान लें कि आपके पास एक क्वेरी है जिसमें एक दृश्य शामिल है, और वह दृश्य 10 तालिकाओं से मिलकर बना है। कहो कि आपकी क्वेरी केवल उन 10 तालिकाओं में से 3 से कॉलम का उपयोग करने के लिए होती है।

यदि उन 10 तालिकाओं को आंतरिक रूप से शामिल किया गया था एक साथ, फिर क्वेरी अनुकूलक उन सब को शामिल होने के लिए भले ही आपकी क्वेरी में ही 7 10 में से टेबल के जरूरत नहीं है के लिए होगा। ऐसा इसलिए है क्योंकि आंतरिक जुड़ाव स्वयं डेटा को फ़िल्टर कर सकता है, जिससे उन्हें गणना करना आवश्यक हो जाता है।

यदि उन 10 तालिकाओं को बाहरी रूप से जोड़ दिया गया था एक साथ बजाय, फिर क्वेरी अनुकूलक केवल वास्तव में जो कि आवश्यक थे शामिल हो जाएगा: इस मामले में 10 में से 3 बाहर उनमें से। ऐसा इसलिए है क्योंकि स्वयं जोड़ अब डेटा को फ़िल्टर नहीं कर रहे हैं, और इस प्रकार अप्रयुक्त जोड़ को छोड़ दिया जा सकता है।

स्रोत: http://www.sqlservercentral.com/blogs/sql_coach/2010/07/29/poor-little-misunderstood-views/


1
"बाहरी-जुड़ाव" के बारे में आपका बयान भ्रामक और संभावित रूप से गलत है। आउटर का अर्थ है कि दूसरी तरफ के डेटा का अस्तित्व नहीं है - और यदि यह NULL को स्थानापन्न नहीं करता है। विशिष्ट परिस्थितियों में RDBMS उन्हें "छोड़ें" (dbenham से उपरोक्त उत्तर देखें) हो सकता है। HOWEVER - बाहरी बनाम आंतरिक आपकी क्वेरी को मौलिक रूप से अलग-अलग परिणाम दे सकते हैं। INNER का अर्थ है - वह परिणाम दें जिसके लिए कोई आइटम BOTH A & B. LEFT OUTER में ए का अर्थ है, और वैकल्पिक रूप से B मौजूद होने पर इसका अर्थ देता है। पहला मामला - आपको कुछ पंक्तियाँ मिलती हैं, दूसरी में आपको सभी पंक्तियाँ मिलती हैं।
रिपवैलन

1
@ripvlan बेशक, बाहरी और आंतरिक जुड़ाव हमेशा विनिमेय नहीं होते हैं। मूल प्रश्न प्रदर्शन के बारे में था, जिसका अर्थ है कि हम उन मामलों के बारे में बात कर रहे हैं जिनमें या तो शामिल हों, वही परिणाम सेट लौटाएगा।
MarredCheese

1
हां और - OUTER एक प्रदर्शन समस्या पैदा कर सकता है क्योंकि यह सभी पंक्तियों (अधिक डेटा) को वापस करने का कारण होगा। आपकी धारणा है कि एक ही आउटपुट में प्रश्नों का परिणाम एक उचित है - हालांकि यह सामान्य मामले में सच नहीं है और प्रत्येक डीबी डिजाइन के लिए विशिष्ट है। और उन लोगों के लिए जो संबंधपरक बीजगणित से 100% परिचित नहीं हैं, उनके कारण दुःख हो सकता है। मेरी बात केवल सलाह के लिए देख रहे लोगों को अधिक जानकारी प्रदान करना है और यह कि LEFT / RIGHT जादुई रूप से किसी समस्या का समाधान नहीं करेगी और अधिक समस्याएँ पैदा कर सकती है। यह स्तर 300 :-)
रिपवैलन

2

मैंने SQL सर्वर में कुछ दिलचस्प पाया जब जाँचता है कि क्या आंतरिक जुड़ाव बाएं जोड़ों से तेज है।

यदि आप बाईं ज्वाइन टेबल के आइटम को शामिल नहीं करते हैं, तो चयन स्टेटमेंट में, लेफ्ट जॉइन आंतरिक क्वेरी के साथ समान क्वेरी से अधिक तेज होगा।

यदि आप चयन किए गए कथन में बाएं सम्मिलित तालिका को शामिल करते हैं, तो उसी क्वेरी के साथ आंतरिक जुड़ाव बाईं जोड़ की तुलना में समान या तेज़ था।


0

मेरी तुलना से, मुझे पता चलता है कि उनके पास सटीक निष्पादन योजना है। तीन परिदृश्य हैं:

  1. यदि और जब वे समान परिणाम लौटाते हैं, तो उनकी गति समान होती है। हालांकि, हमें यह ध्यान रखना चाहिए कि वे एक ही तरह के प्रश्न नहीं हैं, और यह कि LEFT JOIN संभवतः अधिक परिणाम लौटाएगा (जब कुछ शर्तों को पूरा नहीं किया जाता है) --- यही कारण है कि यह आमतौर पर धीमा है।

  2. जब मुख्य तालिका (निष्पादन योजना में पहले गैर-कास्ट) में एक प्रतिबंधात्मक स्थिति होती है (WHERE आईडी =?) और संबंधित चालू स्थिति एक पूर्ण मान पर होती है, तो "सही" तालिका शामिल नहीं होती है --- यह तब है जब बाईं ओर तेजी से होता है।

  3. जैसा कि बिंदु 1 में चर्चा की गई है, आमतौर पर INNER JOIN अधिक प्रतिबंधक है और कम परिणाम देता है और इसलिए तेज है।

दोनों (एक ही) सूचकांकों का उपयोग करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.