【问题标题】:How to query a large table using update command with multiple joins?如何使用具有多个连接的更新命令查询大表?
【发布时间】:2014-05-10 04:56:02
【问题描述】:

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

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'

【问题讨论】:

  • 被引用的列上是否有索引?

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


【解决方案1】:

编辑 正如@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 运算符后面的值是常量。

  • 使用远程连接提示。看看MSDN

远程

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

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

当连接谓词中要比较的值之一使用 COLLATE 子句强制转换为不同的排序规则时,不能使用 REMOTE。

REMOTE 只能用于 INNER JOIN 操作。

【讨论】:

  • When you join local table to a table in remote server, SQL Server data engine will pull all from table in remote and do JOIN in your local memory. SQL Server 可以将查询推送到远程。查询优化器以基于成本的方式做出此决定。
  • @usr 只是补充一点,优化器直到最近才在这里几乎没用,因为它无法使用来自远程服务器的统计信息(除非映射登录是 sys/ddladmin 或 db 用户是数据库或表):connect.microsoft.com/SQLServer/feedback/details/695640/…
  • 感谢您指出我的错误。 2008年或2009年不知道执行计划时,根据我自己的经验。我刚刚在SQL SERVER 2014上尝试过,它确实如你所说。
猜你喜欢
  • 2017-05-25
  • 2018-05-30
  • 2017-08-25
  • 2019-08-28
  • 1970-01-01
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多