it-swarm.dev

هل هناك "أو" في حالة الانضمام إلى الداخل يعد فكرة سيئة؟

في محاولة لتحسين سرعة استعلام بطيء للغاية (عدة دقائق على جدولين مع فقط حوالي 50000 صف لكل منهما ، على SQL Server 2008 إذا كان الأمر مهمًا) ، قمت بتقليص المشكلة إلى 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 في شرط الصلة؟ أو هل أنا محظوظ بطريقة ما في تخطيط جداولي؟

87
ladenedge

لا يمكن تحسين هذا النوع من 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

، مع العلم أن كل واحد منهم عبارة عن equijoin ، فإن محسن SQL Server ليس ذكيًا بما يكفي لرؤيته في الاستعلام الذي كتبته (على الرغم من أنهما متكافئان منطقيا).

103
Quassnoi

يمكنني استخدام التعليمات البرمجية التالية للحصول على نتيجة مختلفة عن الحالة التي عملت بالنسبة لي.


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
MEO