【问题标题】:What to use instead of LEFT REMOTE JOIN用什么代替 LEFT REMOTE JOIN
【发布时间】: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


【解决方案1】:

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

步骤 1)。使用您需要的数据创建一个临时表。 第2步)。如果您想要速度,那么使用 Openquery 是您想要的方式。使用您想要的来自其他服务器的数据创建一个临时表。使用 openquery 和动态 sql 获取您想要过滤的数据。 步骤 3)。使用临时表加入这个。

 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

让我知道它是否有效,亚历克斯

【讨论】:

  • 从 OPENQUERY 访问我的 localTable 很困难。我需要将所有 id 选择为逗号分隔的字符串,然后在动态查询中使用它或将我的本地 SQL Server 连接为远程服务器的链接服务器。
【解决方案2】:

OPENQUERY 可用于将繁重的执行移至适当的服务器,并可以将结果带回。

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

OPENQUERY (Transact-SQL)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 2019-10-09
    • 2015-11-28
    • 2020-03-07
    相关资源
    最近更新 更多