如何使用具有多个连接的update命令查询大型表?

时间:2014-05-10 04:56:02

标签: sql sql-server sql-server-2008 join sql-server-2012

我在外部服务器上有一个大表,我正在尝试在本地计算机上的另一个表上进行更新。外部服务器表超过几十亿行。当我将以下更新作为存储过程运行时,需要很长时间才能给出结果。有没有一种方法可以调整它以便可以将其分解为更小的数据集来进行查询?

update C set C.[P_Flag]='Y'  from [LocalMachine].dbo.O_C_Data C inner
   join [ExternalServer].dbo.E_Extract E on C.[O_ID]=E.[B_ID] and
   C.[P_Option]=E.[P_OPTID] and C.[P]=E.[PD_G]  where C.[O_Flag]='Y'

1 个答案:

答案 0 :(得分:-2)

编辑正如@usr指出的那样,我在下面说的不正确。通过检查执行计划,你可以更好地了解它为什么会很慢,当我遇到同样的问题时,我并没有掌握它。您的查询可能会触发太多执行到远程服务器。这是为了在本地的每一行单独查询远程服务器上的数据。但是,我建议尝试下面的第一种方法。它确实解决过类似的问题。我怀疑你有同样的根本原因。

当您将本地表连接到远程服务器中的表时,SQL Server数据引擎将从远程表中提取所有数据,并在本地内存中执行JOIN。这就是为什么它非常慢。

我建议创建一个本地临时表,插入带有从远程服务器提取的数据的临时表,并使用临时表更新本地表。要实现这一点,您仍然需要JOIN本地表和远程表。有两种方法:

  • 在查询中嵌入本地表。在你的情况下,你能写吗

    INSERT INTO #TempTable
    SELECT E.B_ID
    FROM [ExternalServer].dbo.E_Extract E 
    WHERE E.[B_ID] IN (C_ID1, C_ID2, ...) AND E.[P_OPTID] IN (P_Option1, P_Option2) AND E.[PD_G] IN (P1, P2, ...)
    

注意,IN运算符后的值是常量。

  • 使用REMOTE JOIN提示。看看MSDN
  

<强> REMOTE

     

指定在右表的站点上执行连接操作。当左表是本地表而右表是远程表时,这很有用。仅当左表的行数少于右表时,才应使用REMOTE。

     

如果右表是本地的,则在本地执行连接。如果两个表都是远程的但来自不同的数据源,则REMOTE会导致在右表的站点上执行连接。如果两个表都是来自同一数据源的远程表,则不需要REMOTE。

     

当使用COLLATE子句将连接谓词中要比较的值之一强制转换为其他排序规则时,无法使用REMOTE。

     

REMOTE只能用于INNER JOIN操作。