2014-11-13 4 views
0

Я работаю над уже существующим (проверяя производительность) оператором sql, и я обнаружил, что два предложения для обновления очень похожи, которые используют предложения WHERE IN (Subquery), и я думаю, что они очень медленно, я прошу вашей помощи найти другой способ, которым оба предложения работают, и выполнять работу быстрее.Улучшение производительности при обновлении с помощью WHERE IN Subquery

Вот «Мок» Код

UPDATE Table1 SET IdUser = @NewUserId 
    WHERE IdTask IN 
    (
    SELECT T.IdTask 
    FROM Business N 
    JOIN Process P ON N.IdBusiness = P.CodBusiness 
    JOIN Proyect Pr ON P.CodProyect = Pr.IdProyect 
    JOIN Etap E ON E.CodProyect = Pr.IdProyect 
    JOIN Task T ON T.CodEtap = E.IdEtap 
    WHERE IdBusiness = @IdBusiness AND 
    T.Flag = 0 
    ) 

    UPDATE Table2 SET Flag = 1 
    WHERE CodTask IN 
    (
    SELECT T.IdTask 
    FROM Business N 
    JOIN Process P ON N.IdBusiness = P.CodBusiness 
    JOIN Proyect Pr ON P.CodProyect = Pr.IdProyect 
    JOIN Etap E ON E.CodProyect = Pr.IdProyect 
    JOIN Task T ON T.CodEtap = E.IdEtap 
    JOIN TaskAdvan TA ON TA.CodTask = T.IdTask 
    WHERE IdBusiness = @IdBusiness AND 
    T.Flag = 0 
    ) 

Большое спасибо

+0

Убить подзапрос? Дайте нам планы запросов? – TomTom

+0

Рассмотрите возможность перехода на страницу: http://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join –

ответ

0
--UPDATE using Inner JOIN 

    UPDATE A 
    SET  A.IdUser = @NewUserId 
    FROM Table1 AS A 
      JOIN (SELECT T.IdTask 
        FROM  Business N 
          JOIN Process P 
          ON N.IdBusiness = P.CodBusiness 
          JOIN Proyect Pr 
          ON P.CodProyect = Pr.IdProyect 
          JOIN Etap E 
          ON E.CodProyect = Pr.IdProyect 
          JOIN Task T 
          ON T.CodEtap = E.IdEtap 
        WHERE IdBusiness = @IdBusiness AND 
          T.Flag = 0 
       ) B 
      ON A.IdTask = B.IdTask 
------------------------------------------------------------------------ 
    UPDATE A 
    SET  A.Flag = 1 
    FROM Table2 AS A 
      JOIN (SELECT T.IdTask 
        FROM  Business N 
          JOIN Process P 
          ON N.IdBusiness = P.CodBusiness 
          JOIN Proyect Pr 
          ON P.CodProyect = Pr.IdProyect 
          JOIN Etap E 
          ON E.CodProyect = Pr.IdProyect 
          JOIN Task T 
          ON T.CodEtap = E.IdEtap 
          JOIN TaskAdvan TA 
          ON TA.CodTask = T.IdTask 
        WHERE IdBusiness = @IdBusiness AND 
          T.Flag = 0 
       ) AS B 
      ON A.CodTask = B.IdTask 
+0

Большое спасибо, мне это очень помогает :) –

0

Если вы считаете, что подзапрос дорого процесса, вы можете хранить промежуточные результаты в временную таблицу или табличную переменную. Затем вы можете использовать это в последующих обновлениях.

DECLARE @filter TABLE(IdTask INT PRIMARY KEY) 
INSERT INTO @filter 
SELECT T.IdTask 
FROM Business N 
JOIN Process P ON N.IdBusiness = P.CodBusiness 
JOIN Proyect Pr ON P.CodProyect = Pr.IdProyect 
JOIN Etap E ON E.CodProyect = Pr.IdProyect 
JOIN Task T ON T.CodEtap = E.IdEtap 
WHERE IdBusiness = @IdBusiness AND 
T.Flag = 0 

UPDATE t1 SET IdUser = @NewUserId 
FROM Table1 t1 INNER JOIN @filter f ON f.IdTask = t1.IdTask 

UPDATE t2 SET Flag = 1 
FROM Table2 t2 INNER JOIN @filter f ON f.IdTask = t2.CodTask