SQL链接服务器查询非常非常慢

SQL链接服务器查询非常非常慢,sql,sql-server,tsql,Sql,Sql Server,Tsql,我通过链接服务器从视图中提取大量数据。我使用的是SQL Server 2012,链接服务器是SQL Server 2008 我的select语句是 SELECT * INTO MY_LOCAL_TABLE FROM ( SELECT * FROM LINKEDSERVER.DB.TABLE.VIEW WHERE DATE>'2012-01-01' AND ID IN (SELECT ID FROM MY_LOCAL_VIEW) ) Q 我预计近700多个ID将有30万

我通过链接服务器从视图中提取大量数据。我使用的是SQL Server 2012,链接服务器是SQL Server 2008

我的select语句是

SELECT * INTO MY_LOCAL_TABLE
FROM 
(    SELECT * FROM LINKEDSERVER.DB.TABLE.VIEW
     WHERE DATE>'2012-01-01' AND ID IN (SELECT ID FROM MY_LOCAL_VIEW) 
) Q
我预计近700多个ID将有30万行。以前需要几个小时,但现在需要20多小时

你能为这种疼痛提出其他的解决方案吗


非常感谢

其他人已经建议建立索引。所以我不去那里。如果可以更改内部查询,请建议另一个选项

 SELECT * FROM LINKEDSERVER.DB.TABLE.VIEW
 WHERE DATE>'2012-01-01' AND ID IN (SELECT ID FROM MY_LOCAL_VIEW)
因为您说过有700多个inlist元素,所以使用内部连接来连接查询。试试看

   SELECT lnv.* FROM LINKEDSERVER.DB.TABLE.VIEW lnv
   inner join MY_LOCAL_VIEW mcv
   on lnv.ID = mcv.ID
   and lnv.DATE > '2012-01-01'

当使用由4部分组成的名称(例如[server].db.dbo.table)时,尤其是在联接中,通常会将整个表通过线路复制到本地计算机,这显然是不理想的

一个更好的方法是使用OPENQUERY,它是在源链接服务器上处理的

尝试:

使用这种方法,链接服务器将返回date>x的所有行,然后本地服务器将根据本地表中的ID进行过滤

当然,索引仍然是执行SELECT*FROM DB.TABLE.VIEW WHERE DATE>'2012-01-01的一个因素

我在大型子集上使用的另一种方法是将本地ID转储到远程服务器,然后远程处理,例如:

    -- copy local table to linked server by executing remote query 
    DECLARE @SQL NVARCHAR(MAX)
    SET @SQL = 'SELECT ID INTO db.dbo.tmpTable FROM [SERVER].DB.DBO.MY_LOCAL_VIEW'
    EXEC(@SQL) AT [LINKEDSERVER]

   -- index remote table?!?
    DECLARE @SQL NVARCHAR(MAX)
    SET @SQL = 'CREATE INDEX [IXTMP] ON db.dbo.tmpTable (ID)'
    EXEC(@SQL) AT [LINKEDSERVER]

    -- run query on local machine against both remote tables
    SELECT *
    -- INTO sometable
    FROM OPENQUERY([LINKEDSERVER], 'SELECT * 
                                    FROM DB.TABLE.VIEW
                                    WHERE DATE>''2012-01-01''
                                    AND ID IN (SELECT ID FROM db.dbo.tmpTable)')

    -- now drop remote temp table of id's
    DECLARE @SQL NVARCHAR(MAX)
    SET @SQL = 'DROP TABLE db.dbo.tmpTable'
    EXEC(@SQL) AT [LINKEDSERVER]

如果本地视图也很大,那么您可以考虑执行远程查询,该查询使用OpenQuoice返回本地机器,假设远程机器具有本地作为链接。

-- copy local table to linked server by executing remote query 
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]

视图是否已编入索引?如果没有,它们是否包含子查询?如果没有,您可以为这些视图添加索引。如果这些视图调用其他视图,则会导致性能问题,尤其是在链接服务器上。是,这些视图的索引正确。如果我使用OPENQUERY,有什么区别吗?或SSIS包?此实例中的另一个问题可能是链接服务器的权限<2012 SP1。看看上面列出的第一个问题-权限不足跨服务器连接通常会导致整个表复制到本地计算机,这只能在您负担得起的非常小的表上进行。@JiggsJedi,我在回答中提到过,这也是非常正确的。。这是一个值得尝试一次的建议,但根据我的观察,如果联接的表不够大,这将在大多数情况下提高性能。+1确实是一个很好的方法。我不知道这个我是说openquery因子。。。我觉得这是个好主意。我不确定我是否有权在链接服务器上创建临时表,但我肯定会尝试您的建议,因为链接服务器包含超过50K个ID!!thanksIt可以将ID放入一个真正的临时表中——每个人都应该有权创建它们,并一次性运行。您也可以在tempdb中创建用户表,而不必在工作数据库中。谢谢。真的很感激!如果无法在tempdb中设置TABLE,则可以将所有ID连接在一起,并在openquery中使用“SELECT*FROM DB.TABLE.VIEW WHERE DATE>”2012-01-01和“+@concatednatedListOfIds+中的ID。你说名单没那么长。如果你的列表很长,那么这可能不是一个好主意。
-- copy local table to linked server by executing remote query 
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]