1

У меня есть SQL-запрос (MS SQL 2008), который я бы хотел оптимизировать по скорости. Он имеет следующую структуру (только в действительности в заявлении дела есть 10 разных случаев).Как оптимизировать условные подвыборки, которые связаны с внутренними соединениями?

Важные биты - это подвыборы в заявлении case, которые включают внутренние соединения между дополнительными таблицами и ссылку на одну из таблиц в предложении FROM (таблица1).

Я думал, что могу оптимизировать это, используя левое (внешнее) объединение в предложении FROM вместо подбора select, но не уверен, потому что sub выбирает также также внутренние соединения. Могу ли я использовать два левых соединения в предложении FROM, где теперь я использую внутреннее соединение в подборах? И как это будет работать с AnotherTable3 со второго в случае?

Любые идеи очень ценятся.

SELECT table1.a, 
      table2.b, 
      CASE 
      WHEN table1.XY = 1 THEN 
       (SELECT something 
       FROM AnotherTable1 at1 
         INNER JOIN AnotherTable2 at2 
           ON at1.x = at2.y 
       WHERE at1.abc = table2.abc) 
      WHEN table1.XY = 2 THEN 
       (SELECT something 
       FROM AnotherTable1 at1 
         INNER JOIN AnotherTable3 at3 
           ON at1.x = at3.y 
       WHERE at1.abc = table2.abc) 
      END AS [problem] 
    FROM MyTable1 table1 
      INNER JOIN MyTable2 table2 
        ON table1.a = table2.b 
+0

В таких случаях я обычно пишу 'выбрать ... от MayTable1 table1 ... осталось присоединиться (выбрать ... от AnotherTable1 АТ1 ...) АТ1 на at1.abc = table2.abc и table1.XY = 1 ... ' – Claude

+0

Сравните [этот вопрос и его ответы] (http://stackoverflow.com/questions/15384979/case-clause-execution-procedure) – Claude

ответ

0

данных В этом частном случае, когда AnotherTable1 соединяется в как при частях с одинаковым условием вам понадобятся только три левых соединения:

SELECT table1.a, 
     table2.b, 
     CASE 
     WHEN table1.XY = 1 THEN 
      ?.something -- from whereever it's coming 
     WHEN table1.XY = 2 THEN 
      ?.something -- from whereever it's coming 
     END AS [problem] 
FROM MyTable1 table1 
     INNER JOIN MyTable2 table2 
       ON table1.a = table2.b 
     LEFT JOIN AnotherTable1 at1 
       ON at1.abc = table2.abc 
     LEFT JOIN AnotherTable2 at2 
       ON at1.x = at2.y 
     LEFT JOIN AnotherTable3 at3 
       ON at1.x = at3.y 

В более общий случай вы бы этот вариант

FROM MyTable1 table1 
     INNER JOIN MyTable2 table2 
       ON table1.a = table2.b 
     LEFT JOIN 
      (select * 
       from AnotherTable1 at1 
       INNER JOIN 
        AnotherTable2 at2 
         ON at1.x = at2.y 
      ) at1 
       ON at1.abc = table2.abc 
     ... 
0

Вы можете попробовать следующее:

SELECT 
    table1.a, 
    table2.b, 
    CASE 
     WHEN table1.XY = 1 THEN at2.something 
     WHEN table1.XY = 2 THEN at3.something 
    END 
FROM MyTable1 table1 
INNER JOIN MyTable2 table2 
    ON table1.a = table2.b 
LEFT JOIN AnotherTable1 at1 
    ON at1.abc = table2.abc 
INNER JOIN AnotherTable2 at2 
    ON at1.x = at2.y 
INNER JOIN AnotherTable3 at3 
    ON at1.x = at3.y 

Но проверить результаты, а также иметь в виду, что АТ2 и aT3 столбцы должны иметь одинаковый тип

+0

Это кажется неправильным: когда левое соединение между at1 и table2 оценивает at1 до нуля, тогда внутреннее соединение между at1 и at2 терпит неудачу, и строка теряется. Это отличается от исходного запроса. – Claude

+0

строка также будет потеряна в исходном запросе, я не знаю схему db, поэтому угадайте, есть ли внешний ключ или что-то еще, потому что @DotNetDeveloper делает это таким образом – Sergio

+0

У меня получается меньше результатов таким образом , проблема, как сказал Майкл выше. Я думаю, проблема заключается в том, что INNER JOIN AnotherTable2 at2 не только означает внутреннее соединение в предыдущем левом соединении, но и во всех данных. – DotNetDeveloper

Смежные вопросы