【发布时间】:2015-09-24 13:16:37
【问题描述】:
我有两个链接的 SQL Server (2008R2)。远程服务器包含一个包含大量行的表。它必须与本地表连接。在这种情况下,一个好的解决方案是对JOIN 使用REMOTE 提示。
但是使用REMOTE JOIN有一个限制:
REMOTE 只能用于 INNER JOIN 操作。
我想做一个左连接操作,但是会在本地完成,整个 HugeRemoteTable 会被加载到本地服务器上:
SELECT HugeRemoteTable.*
FROM HugeRemoteTable
LEFT JOIN LocalTable
ON HugeRemoteTable.col = LocalTable.id
WHERE LocalTable.id IS NULL
是否可以重写查询以连接远程端的表并仅加载过滤后的数据?
EDIT1:
我对查询进行了试验,如果条件为LocalTable.id IS NULL,SQL Server 会远程运行查询。查询需要一些时间。
但条件为LocalTable.id IS NOT NULL 的查询需要更多时间,而且显然在本地运行。
同样的行为展示了将 JOIN 重写为 NOT IN 或 IN 的查询(它们甚至具有类似于使用 JOIN 的查询计划的执行计划)。
这个查询运行得非常快:
SELECT *
FROM HugeRemoteTable
WHERE col NOT IN (SELECT id FROM LocalTable)
而且这需要很多时间并且会向远程服务器生成大量请求(我不知道确切原因,但看起来本地服务器从 LocalTable 的每一行都发出请求):
SELECT *
FROM HugeRemoteTable
WHERE col IN (SELECT id FROM LocalTable)
现在我们要去OPENQUERY。我已使用别名“localServer”将本地服务器连接为远程 SQL Server 的链接服务器(相反方向),并以这种方式以 OPENQUERY 开始
SELECT * FROM OPENQUERY(remote,'
SELECT * FROM HugeRemoteTable
LEFT JOIN localServer.localTable ON HugeRemoteTable.col=localTable.id
WHERE localTable.id is not null')
它和条件LocalTable.id IS NULL查询一样快
SELECT * FROM OPENQUERY(remote,'
SELECT * FROM HugeRemoteTable
LEFT JOIN localServer.localTable ON HugeRemoteTable.col=localTable.id
WHERE localTable.id is null')
使用 OPENQUERY 的两个查询都非常快,但它们需要在服务器之间进行双向链接。
还有其他解决方案吗?
【问题讨论】:
-
可能带有 WHERE IN(子查询)?
-
@TabAlleman not in - 可能从 HugeRemoteTable 中选择 *,其中 HugeRemoteTable.col 不在(从 LocalTable 中选择 Id)
-
啊,我并没有真正阅读他的查询,我只是看到了 LEFT JOIN,然后想到了“WHERE IN”。我没有看到他想用它来排除本地表中的匹配项。很好的收获。
-
制表符,克莱谢谢你。我尝试了您提出的查询并用我的结果更新了问题。
标签: sql-server join sql-server-2008-r2 linked-server