在不同数据库上使用Inner Join的SQL Update

时间:2017-07-29 07:24:28

标签: sql-server database tsql join

我正在尝试使用内连接更新表中的数据,其中包含来自不同数据库中另一个表的数据。数据量非常大,这导致执行时间超过10小时,这让我觉得我的查询可能有问题。

UPDATE [Database1]..[Table1]  
SET [Database1]..[Table1].Table1BitValue = 
         CASE 
            WHEN ([Database2]..[Table2].Table2BitValue IS NULL 
                  OR [Database2]..[Table2].Table2BitValue = 0) 
               THEN 0 
               ELSE 1 
         END 
FROM  [Database1]..[Table1]  
INNER JOIN [Database2]..[Table2] ON [Database2]..[Table2].[Table2Id] = [Database1]..[Table1] .[Table1Id]

2 个答案:

答案 0 :(得分:1)

您可以尝试以块的形式更新表格。 想法是避免因大量行而锁定整个表

DECLARE @maxID INT,
        @startRange INT,
        @endRange INT,
        @batchSize INT; -- keep below 5000 to be safe

SET @batchSize = 2000;
SET @startRange = 0;
SET @endRange = @batchSize;

SET @maxID = 1;
SELECT @maxID = max([Table1Id]) FROM [Database1]..[Table1]    

BEGIN TRY    
  WHILE (@startRange < @maxID)
  BEGIN

  UPDATE [Database1]..[Table1]  
  SET [Database1]..[Table1].Table1BitValue = 
         CASE 
            WHEN ([Database2]..[Table2].Table2BitValue IS NULL 
                  OR [Database2]..[Table2].Table2BitValue = 0) 
               THEN 0 
               ELSE 1 
         END 
   FROM  [Database1]..[Table1]  
   INNER JOIN [Database2]..[Table2] ON [Database2]..[Table2].[Table2Id] = [Database1]..[Table1].[Table1Id]
   WHERE [Database1]..[Table1].[Table1Id] BETWEEN @startRange AND @endRange;

  SET @startRange = @endRange + 1;
  SET @endRange = @endRange + @batchSize;
  END;
END TRY

BEGIN CATCH
 -- Add your code for: RAISERROR();
  RETURN;
END CATCH;

这只是分块的想法,您可以根据自己的需要进行修改。 Haven未经过验证,请在执行上述脚本之前进行验证

答案 1 :(得分:0)

如果可能的话,您需要稍微帮助优化器并将过滤器放到远程表上。否则,它将拉回远程表中的所有行以满足连接。

以下是其他攻击方式:

https://blogs.technet.microsoft.com/pfelatam/2011/09/07/linked-server-behavior-when-used-on-join-clauses/