1. 程式人生 > >連結伺服器使用OPENQUERY效能提升

連結伺服器使用OPENQUERY效能提升

從哪找的記不清了,記錄一下,使用OPNQUERY提升效能


1. 問題
  系統有個模組,需要查詢Oracle資料庫中的資料。目前是通過建立連結伺服器實現的。

  目前的查詢語句就是一個簡單的帶where條件的查詢語句,類似如下:


SELECT*FROM LINKED_NAME..ACCOUNT_NAME.TABLE_NAME WHERE COLUMN1=SID;


  存在的問題是查詢速度非常慢,前臺報超時。所以準備提升下查詢的效能

2. 分析
  首先,確定遠端Oracle的表在篩選欄位上是否存在索引。經確認,存在索引。

  然後,在SSMS客戶端中查看了執行語句的執行計劃,如下:

  從執行計劃可以看出,過程沒有和自己設想的那樣,原以為SQLServer會將整個查詢提交到Oracle伺服器執行。而實際在遠端查詢時,並沒有加入where條件,而是將結果返回到本地後,在本地執行篩選(有一個篩選器)

  這樣速度肯定會非常慢,因為查詢沒有使用到索引查詢,需要將遠端資料全部傳輸到本地後才執行篩選,相當於全表掃描,還多了網路傳輸的時間。

3. 解決
  其實只要能將帶where條件的查詢語句一併提交到Oracle伺服器執行遠端查詢,就可以解決效能問題了。

  但問題是OpenQuery不支援引數。見微軟MSDNhttp://technet.microsoft.com/zh-cn/library/ms188427.aspx

  但好在我們可以另闢蹊徑,通過拼接動態SQL的方式實現傳遞查詢引數。

  通過這種方式優化後,執行計劃變為如下:可以看到實際返回的行數很少了

  查詢速度提升明顯,由原來的前臺超時到現在的毫秒級。 ??

SQL 在OPENQUERY中使用引數
OpenQuery 是SQL Server用來與其他Server互動的一種技術,通過OpenQuery,SQL Server 可以直接訪問其他資料庫資源。而其他資料庫在OpenQuery 表示式中是以Linked Server 存在的。 使用sp_linkedservers 可以找到當前資料庫的所有linked server. OpenQuery的表示式可以這麼寫:

Select * from OpenQuery([linkedServerName],'Select * from table1 where rownum < 10')而且值得注意的是,如果,你要在OpenQuery中執行如下的資料庫語句,

Select * from tbl_emp Where empName = 'leo''leo' 必須以單引號的形式傳人,如下,

Select * from OpenQuery([linkedServerName],'Select * from table1 where empName = ''leo''')


DECLARE @Sql VARCHAR(1000)DECLARE @organizationID VARCHAR(10)SELECT @organizationID = (SELECT ORGANIZATION_ID FROM MYORGS WHERE ORGANIZATION_NAME = 'MMT')SET @Sql = 'SELECT * from tableName where organization_id ='[email protected] SET @Sql = 'SELECT * FROM OPENQUERY(BETSYCRP2, ''' + REPLACE(@Sql, '''', '''''') + ''')'EXEC(@Sql)