連結伺服器使用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)