前言: 本文是對博客http://www.dbnewsfeed.com/2012/09/08/5-performance-killers-when-working-with-linked-servers/的翻譯, 如有翻譯不對或不好的地方,敬請指出,大家一起學習進步。尊重原創和翻譯勞動成果,轉載時請注明出處。謝謝!
當使用鏈接服務器(Linked Servers)時,最昂貴的代價就是網絡帶寬間大量數據的傳輸。在正確的服務器書寫正確的代碼是非常重要的,因為每一個錯誤都會導致在網絡帶寬上付出非常昂貴的代價。 下面是使用鏈接服務器(Linked Servers)時的幾個常見錯誤:
1:使用推送方式而不是拉方式取數
出人意料之外的是,使用鏈接服務器推送數據比拉取數據慢得多。Linchi Shea寫了一篇很好的博客討論這個。
Linchi Shea 使用openquery來說明兩者間的差異,但是這個也會發生在使用鏈接服務器的SQL語句中(這里不好翻譯,其實就是查詢中使用Linked Server需要用到 LinkServer.DatabaseName.dbo.TableName)
2: 使用JOIN
跨服務器查詢時,為了在兩臺服務器之間的數據集之間執行JOIN操作,SQL Server需要將數據從一臺服務器傳送到另外一臺服務器。如果傳送的數據是一個非常大的表,這個過程可能會非常痛苦。通常來說,數據會從遠程服務器傳送到本地服務器。為了防止大量數據在服務器之間大傳送,你可以通過在查詢條件中過濾數據,通過一個遠程存儲過程只取回相關數據來達到目的,萬一你需要使用INNER JOIN關聯兩個不同服務器之間的數據集,而且本地表的數據量遠小于遠程服務器的那個表。你可以使用REMOTE JOIN HINT, 這樣就會將數據從本地服務器將數據傳送到遠程服務器,從而提高性能
3:使用UNION
正如JOIN操作,UNIION不同服務器之間的兩個數據集必定導致從遠程服務器傳送數據到本地服務器。即使你執行遠程查詢合并(UNION)同一個遠程服務器的兩個數據集,還是會先將兩個數據集傳送到本地服務器,然后UNION兩個數據集,可以通過遠程存儲過程,函數或視圖先UNION數據庫來阻止這個
4:書寫太復雜的查詢語句
優化器不能總是能明白你需要做什么,尤其是你的SQL語句中使用了鏈接服務器(Linked Server)時,例如, 我遇到過一個類似如下SQL語句,執行了10分鐘
1: SELECT *
2: FROM LocalTable
3: WHERE SomeColumn <
4: (SELECT COUNT(*)
5: FROM RemoteServer.SomeDB.dbo.SomeTable
6: WHERE SomeColumn > 100)
我像這樣修改了查詢語句
1: DECLARE @Count INT
2: SELECT @Count = COUNT(*)
3: FROM RemoteServer.SomeDB.dbo.SomeTable
4: WHERE SomeColumn > 100
5:
6: SELECT *
7: FROM LocalTable
8: WHERE SomeColumn < @Count
這樣重寫SQL后,查詢語句只跑了一秒就查詢出結果了,保持SQL腳本簡單。
5:當數據庫位于同一個實例時使用鏈接服務器(Linked Server)
這種場景的性能損耗可能不像其它場景那樣明顯,但是這種方式比使用數據庫前綴(Database.dbo.TableName)要慢
如果你想區別這兩種情形,可以在測試數據庫測試、對比這兩種方法的性能,然后決定性能的提升是否值得在生產環境修改代碼。在某些情況下,它是會提升性能的。
---------------------------------------自己的體會、理解------------
新聞熱點
疑難解答