2012-08-11 45 views
5

我有些標識插入到一個臨時表#A如下:兩個查詢。相同的輸出。一個需要2個小時,另一個需要0秒。爲什麼?

SELECT DISTINCT ID 
INTO #A 
FROM LocalDB.dbo.LocalTable1 
WHERE ID NOT IN (SELECT DISTINCT ID FROM LocalDB.dbo.LocalTable2) 
GO 

CREATE INDEX TT ON #A(ID) 
GO 

我試圖獲得使用我收集前一階段標識符從遠程鏈接服務器的一些信息:

查詢1:

SELECT ID, Desc 
FROM RemoteLinkedServer.DB.dbo.RemoteTable X 
WHERE ID IN (SELECT ID FROM #A) 

問題2:

SELECT ID, Desc 
FROM RemoteLinkedServer.DB.dbo.RemoteTable X 
INNER JOIN #A Y 
ON X.ID = Y.ID 

現在,在下面的查詢,我在做什麼是獲得臨時表的輸出,複製行,正常格式化成一個逗號分隔的列表,並手動將它放在查詢。

問題3:

SELECT ID, Desc 
FROM RemoteLinkedServer.DB.dbo.RemoteTable X 
WHERE ID IN (-- Put all identifiers here --) 

查詢12需要2小時才能執行和查詢3取0秒(我的臨時表中包含約200行)。我不知道發生了什麼,也沒有權限檢查遠程服務器是否在ID上具有相關索引,但是看到手動構建的查詢很快就會運行,表示出現了問題在查詢優化階段。

關於這裏出了什麼問題或者我如何加快查詢的想法?

回答

10

查詢1和2導致RemoteTable中的所有數據都被拉入本地數據庫以執行連接操作。這將消耗RAM,網絡帶寬,並且在查詢執行時通常非常緩慢。

查詢3允許遠程服務器篩選結果以僅發送所需的匹配結果。

基本上,它歸結爲誰做了這項工作。查詢1/2需要您的本地數據庫執行此操作;查詢3讓遠程人員執行此操作。

如果你有很多遠程表的數據,那麼你可能會遇到網絡擁塞等

來查詢鏈接的服務器是構建您的查詢,如遠程服務器做所有的最好的方法這項工作只是把結果發回你的本地。這將優化獲取所需數據所需的網絡,內存和磁盤資源的數量。

任何時候你必須跨越服務器邊界(使用鏈接服務器),這將是一場災難。

+1

+1老實說,我不知道!謝謝你的澄清。那麼如何將我的本地值發送到遠程鏈接服務器並獲取結果呢? 'CURSOR',然後一次發送一個標識符?遠程桌子很大,有大約1000萬行。 – Legend 2012-08-11 00:42:10

+2

也許你最好的選擇是動態構建sql來針對遠程服務器執行,並且只需EXEC它。我們發現,對於我們對鏈接服務器進行的每種類型的調用,這種方法要快得多。使用遊標,然後一次運行一個查詢可能會導致您達到交易速度限制;你可能不想要。 – NotMe 2012-08-11 00:46:36

+0

謝謝你的建議。沒有更多的瓶頸和我的腳本運行良好的優化。 – Legend 2012-08-11 05:52:45

3

僅供參考,我這是怎麼解決的基礎上@ ChrisLively的建議問題:

SELECT DISTINCT ID 
INTO #A 
FROM LocalDB.dbo.LocalTable1 
WHERE ID NOT IN (SELECT DISTINCT ID FROM LocalDB.dbo.LocalTable2) 
GO 

CREATE INDEX TT ON #A(ID) 
GO 

DECLARE @IDList VARCHAR(MAX) 
SELECT @IDList=(SELECT TOP 1 REPLACE(RTRIM((
       SELECT DISTINCT CAST(ID AS VARCHAR(MAX)) + ' ' 
       FROM #A AS InnerTable    
       FOR XML PATH (''))),' ',', ')) 
FROM #A AS OuterResults 


DECLARE @sql AS varchar(MAX) 
SET @sql = 'SELECT * FROM RemoteLinkedServer.RemoteDB.dbo.RemoteTable X WHERE ID IN (' + @IDList + ')' 

EXEC (@sql) 

DROP TABLE #A 
GO 
+0

這正是我如何接近它。 – NotMe 2012-08-11 01:09:29

+0

@ChrisLively:謝謝你的確認:) – Legend 2012-08-11 05:51:47

相關問題