我有两个链接的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
的查询已重新命名为IN
或SELECT *
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的两个查询都非常快,但它们需要在服务器之间进行双向链接。
还有其他解决方案吗?
答案 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子句或其他连接类型(编辑:除非您在左侧指定小表以匹配大表中的行他们存在)。