首页 文章

使用什么而不是LEFT REMOTE JOIN

提问于
浏览
2

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

但是使用 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 ININ (它们甚至具有类似于JOIN查询计划的执行计划) .

此查询运行速度非常快:

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

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

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

现在我们要去 OPENQUERY . 我've connected my local server as linked server for remote SQL Server (in opposite direction) using alias ' localServer'并以这种方式从 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的两个查询都非常快,但它们需要服务器之间的双向链接 .

还有其他解决方案吗?

2 回答

  • 0

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

    步骤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

    OPENQUERY可用于将繁重的执行移动到适当的服务器,并可以返回结果 .

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

    OPENQUERY (Transact-SQL)

相关问题