使用什么而不是LEFT REMOTE JOIN

时间:2015-09-24 13:16:38

标签: sql-server join sql-server-2008-r2 linked-server

我有两个链接的SQL Server(2008R2)。远程服务器包含一个包含大量行的表。它必须与本地表连接。在这种情况下,一个好的解决方案是使用REMOTE JOIN的{​​{3}}提示。

但使用SELECT HugeRemoteTable.* FROM HugeRemoteTable LEFT JOIN LocalTable ON HugeRemoteTable.col = LocalTable.id WHERE LocalTable.id IS NULL

有限制
  

REMOTE只能用于INNER JOIN操作。

我想进行左连接操作,但它将在本地完成,整个HugeRemoteTable将加载到本地服务器上:

LocalTable.id IS NULL

是否可以重写查询以连接远程端的表并仅加载过滤后的数据?

EDIT1:

我用查询进行了实验,看起来如果条件为LocalTable.id IS NOT NULL,SQL Server会远程运行查询。查询需要一些时间。

但条件为JOIN的查询需要花费更多时间,显然是在本地运行。

相同的行为表明NOT IN的查询已重新命名为INSELECT * FROM HugeRemoteTable WHERE col NOT IN (SELECT id FROM LocalTable) (他们的执行计划甚至类似于使用JOIN查询的计划)。

此查询运行得非常快:

SELECT *
FROM HugeRemoteTable
WHERE col IN (SELECT id FROM LocalTable)

这个需要花费大量时间并向远程服务器生成大量请求(我不确切知道原因,但看起来本地服务器从LocalTable每行发出请求):

OPENQUERY

现在我们要OPENQUERY。我使用别名“localServer”将我的本地服务器连接为远程SQL Server的链接服务器(反方向),并以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')

的查询一样快
sudo gem install cocoapods

使用OPENQUERY的两个查询都非常快,但它们需要在服务器之间进行双向链接。

还有其他解决方案吗?

2 个答案:

答案 0 :(得分:1)

如果您正在寻找速度并使用链接服务器,请尝试一下。

步骤1)。使用您需要的数据创建临时表。 第2步)。如果你想要速度,使用Openquery是你想要的方式。使用所需数据从其他服务器创建临时表。使用openquery和动态sql获取要过滤的数据。 第三步)。使用临时表来加入它。

 DECLARE @FlatTSQL varchar(8000)
DECLARE @AsOfDate date = '9/24/2015'

CREATE TABLE #MyData
(AsOfDate date)


SELECT  @FlatTSQL = 'SELECT * FROM OPENQUERY(EUC,''
                                               SELECT 
                                                cal.AsOfDate
                                                FROM RiskReporting.Reference.lkpCalendar cal WITH(NOLOCK)
                                                WHERE CONVERT(date,cal.AsOfDate) = ''''' + CONVERT(varchar(25),@AsOfDate) + ''''''')'


INSERT INTO #MyData
EXEC (@FlatTSQL)

SELECT
*
FROM #MyData md

DROP TABLE #MyData

让我知道它是否有效,Alex

答案 1 :(得分:0)

OPENQUERY可用于将繁重的执行移动到适当的服务器,结果可以恢复。

您的左连接本身不会过滤行,因此您必须在远程查询中指定where子句或其他连接类型(编辑:除非您在左侧指定小表以匹配大表中的行他们存在)。

OPENQUERY (Transact-SQL)