Имеет ли "OR" в состоянии INNER JOIN плохую идею?

При попытке улучшить скорость чрезвычайно медленного запроса (несколько минут на двух таблицах с количеством ~ 50 000 строк каждый, на 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 в условие соединения? Или мне просто не повезло в макете моих таблиц?

+84
05 мая '11 в 17:26
источник поделиться
3 ответа

Этот тип 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 недостаточно умен, чтобы видеть его в запросе, который вы написали (хотя они логически эквивалентны).

+102
05 мая '11 в 17:37
источник

Я использую следующий код для получения другого результата из условия Это сработало для меня.


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
21 дек. '17 в 18:21
источник
другие ответы

Связанные вопросы


Похожие вопросы

Вместо этого вы можете использовать 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

0
21 янв. '19 в 10:22
источник

Посмотрите другие вопросы по меткам или Задайте вопрос