当您使用类似 [server].db.dbo.table
这样的四部分名称,特别是在 join
中时,往往会将整个表格复制到本地机器上,显然这并不理想。
更好的方法是使用 OPENQUERY
-- 这是在源(链接服务器)处处理的。
请尝试:
SELECT *
FROM OPENQUERY([LINKEDSERVER], 'SELECT * FROM DB.TABLE.VIEW WHERE DATE>'2012-01-01')
AND ID IN (SELECT ID FROM MY_LOCAL_VIEW)
采用这种方法,关联服务器会返回日期大于x的所有行,然后本地服务器会通过本地表中的ID进行过滤。
当然,索引仍然在执行SELECT * FROM DB.TABLE.VIEW WHERE DATE>'2012-01-01'
时起到了作用。
另一种我在大型子集上使用的方法是将本地ID转储到远程服务器,然后全部在远程处理,例如:
DECLARE @SQL NVARCHAR(MAX)
SET @SQL = 'SELECT ID INTO db.dbo.tmpTable FROM [SERVER].DB.DBO.MY_LOCAL_VIEW'
EXEC(@SQL) AT [LINKEDSERVER]
DECLARE @SQL NVARCHAR(MAX)
SET @SQL = 'CREATE INDEX [IXTMP] ON db.dbo.tmpTable (ID)'
EXEC(@SQL) AT [LINKEDSERVER]
SELECT *
FROM OPENQUERY([LINKEDSERVER], 'SELECT *
FROM DB.TABLE.VIEW
WHERE DATE>''2012-01-01''
AND ID IN (SELECT ID FROM db.dbo.tmpTable)')
DECLARE @SQL NVARCHAR(MAX)
SET @SQL = 'DROP TABLE db.dbo.tmpTable'
EXEC(@SQL) AT [LINKEDSERVER]
如果本地视图也很大,那么您可以考虑执行一个远程查询,使用 openquery 返回到本地机器(假设远程机器将本地作为链接)。
如果本地视图也很大,那么您可以考虑执行一个远程查询,使用 openquery 返回到本地机器(假设远程机器将本地作为链接)。
DECLARE @SQL NVARCHAR(MAX)
SET @SQL = 'SELECT ID INTO db.dbo.tmpTable FROM OPENQUERY([SERVER], ''SELECT ID FROM DB.DBO.MY_LOCAL_VIEW'')'
EXEC(@SQL) AT [LINKEDSERVER]