एक ININ JOIN स्थिति में 'OR' एक बुरा विचार है?


94

बेहद धीमी गति से क्वेरी की गति को बेहतर बनाने की कोशिश में ( SQL सर्वर 2008 पर अगर यह मायने रखता है, तो प्रत्येक ~ केवल 50,000 पंक्तियों के साथ दो तालिकाओं पर कई मिनट ), मैंने समस्या को ORअपनी आंतरिक जॉइन में संकुचित कर दिया , जैसे कि:

SELECT mt.ID, mt.ParentID, ot.MasterID
  FROM dbo.MainTable AS mt
  INNER JOIN dbo.OtherTable AS ot ON ot.ParentID = mt.ID
                                  OR ot.ID = mt.ParentID

मैंने इसे (जो मुझे आशा है कि) बाएँ जोड़ के बराबर जोड़ा, यहाँ दिखाया गया है:

SELECT mt.ID, mt.ParentID,
   CASE WHEN ot1.MasterID IS NOT NULL THEN
      ot1.MasterID ELSE
      ot2.MasterID END AS MasterID
  FROM dbo.MainTable AS mt
  LEFT JOIN dbo.OtherTable AS ot1 ON ot1.ParentID = mt.ID
  LEFT JOIN dbo.OtherTable AS ot2 ON ot2.ID = mt.ParentID
  WHERE ot1.MasterID IS NOT NULL OR ot2.MasterID IS NOT NULL

.. और क्वेरी अब लगभग एक सेकंड में चलती है!

क्या आम तौर पर ORजॉइन करने की स्थिति में यह एक बुरा विचार है ? या मैं अपनी टेबल के लेआउट में किसी तरह से बदकिस्मत हूं?


6
अपनी क्वेरी के बजाय निष्पादन योजना हमें दिखाएं।
ब्लाइंडी

एक अजीब रिश्ते की तरह लगता है
nathan gonzalez

@ ब्लिंडी: अच्छा विचार है। यह पता चलता है कि निष्पादन की योजनाएं केवल नीचे दी गई क्वासोई का उल्लेख करती हैं: पहली क्वेरी का परिणाम नेस्टेड लूप में होता है, जबकि दूसरा हैश जॉइन के साथ होता है।
ladenedge

जवाबों:


114

इस तरह का JOINएक HASH JOINया एक के लिए अनुकूलन योग्य नहीं है MERGE JOIN

इसे दो परिणामों के संघटन के रूप में व्यक्त किया जा सकता है:

SELECT  *
FROM    maintable m
JOIN    othertable o
ON      o.parentId = m.id
UNION
SELECT  *
FROM    maintable m
JOIN    othertable o
ON      o.id = m.parentId

, उनमें से प्रत्येक समतुल्य है, हालांकि, SQL Serverआपके द्वारा लिखे गए प्रश्न में इसे देखने के लिए ऑप्टिमाइज़र पर्याप्त स्मार्ट नहीं है (हालांकि वे तार्किक रूप से समकक्ष हैं)।


3
यह समझ में आता है, धन्यवाद। मुझे अभी भी यकीन नहीं है कि मेरी क्वेरी के बारे में कुछ अजीब है, या अगर मुझे ON w=x OR y=zपूरी तरह से पैटर्न के जोड़ों से बचना चाहिए ?
ladenedge

@ladenedge: नेस्टेड लूप में इन स्कैन को टेबल स्कैन का उपयोग करके किया जाएगा। यदि आपकी टेबल बड़ी हैं तो यह धीमी है।
क्वासोई

बस स्पष्ट होने के लिए, जब आप कहते हैं "ये जुड़ते हैं," तो आपका मतलब है कि सभी प्रकार के जोड़ ON w=x OR y=z? (आपके धैर्य के लिए धन्यवाद!)
18

3
@ प्रचार: अतिरिक्त शर्तें हो सकती हैं जो यह SQL Serverसमझने में मदद कर सकती हैं कि एक सहमति की आवश्यकता होगी। कहते हैं, SELECT * FROM othertable WHERE parentId = 1 OR id = 2यदि दोनों क्षेत्रों को अनुक्रमित किया जाता है तो क्वेरी एक संघनन का उपयोग करेगी यदि सैद्धांतिक रूप से ऐसा कुछ भी नहीं है जो एक लूप में एक ही काम करने से रोकता है। चाहे SQL Serverयह योजना वास्तव में है या नहीं का निर्माण करेगा, बहुत कई कारकों पर निर्भर है, लेकिन मैं कभी नहीं देखा है यह वास्तविक जीवन में बनाया गया।
क्वासोई

4

मेरे लिए काम करने वाली स्थिति से अलग परिणाम प्राप्त करने के लिए मैं निम्नलिखित कोड का उपयोग करता हूं।


Select A.column, B.column
FROM TABLE1 A
INNER JOIN
TABLE2 B
ON A.Id = (case when (your condition) then b.Id else (something) END)

-2

आप इसके बजाय UNION ALL का उपयोग कर सकते हैं।

SELECT mt.ID, mt.ParentID, ot.MasterID FROM dbo.MainTable AS mt Union ALL SELECT mt.ID, mt.ParentID, ot.MasterID FROM dbo.OtherTable AS ot


UNION ALLआपको JOINएक ORशर्त के साथ डुप्लिकेट देगा ।
कोडमोंकी

उसके लिए UNION सही रहेगा। अधिक जानकारी के लिए निम्नलिखित लिंक संघ-के-या
मितुल पांचाल

1
हां, लेकिन आपके उदाहरण में आपने इसे लिखा है, union allजो आपके द्वारा लिंक किए गए लेख के अनुसार सही नहीं है।
कोडमोंकी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.