在上一遍文章中介紹了SQLServer通過鏈接服務器訪問Oracle性能問題的解決方法,本文介紹鏈接服務器下遠程刪除SQLServer數據的性能問題解決
1. 問題發現
系統中有個功能,需要遠程刪除SQLServer實例的表數據,刪除語句中有where條件,條件中有一個子查詢。
該功能前台執行速度非常慢。所以准備調優。
下面為演示代碼,未優化前如下:
DELETE
FROM [LINKSERVERNAME].[AdventureWorks2008].[Sales].[SalesOrderDetail]
WHERE SalesOrderDetailID=5
AND EXISTS(SELECT TOP 1 1 FROM [LINKSERVERNAME].[AdventureWorks2008].[Sales].[SalesOrderDetail])
此時的執行計划如下圖:
可以看到執行計划存在一個遠程掃描,然后在本地執行篩選。
在遠程服務器開啟profiler跟蹤,部分內容如下圖:
可以看到遠程服務器開啟了一個游標,然后逐行讀取數據並返回給調用端。
可以預見性能會非常差,如何避免不帶where條件的遠程掃描呢?
2. 問題解決
2.1 OpenQuery
使用OpenQuery將delete數據的篩選提交到遠程服務器執行。
DELETE
FROM OPENQUERY([LINKSERVERNAME] ,'SELECT * FROM [AdventureWorks2008].[Sales].[SalesOrderDetail] WHERE SalesOrderDetailID=5 AND EXISTS(SELECT TOP 1 1 FROM [AdventureWorks2008].[Sales].[SalesOrderDetail])' )
此時,執行計划如圖:
2.2 sp_executesql
將整個delete語句提交到遠程執行
DECLARE @sql nvarchar(max) SELECT @sql =' DELETE FROM [AdventureWorks2008].[Sales].[SalesOrderDetail] WHERE SalesOrderDetailID=5 AND EXISTS(SELECT TOP 1 1 FROM [AdventureWorks2008].[Sales].[SalesOrderDetail]) '
exec [LINKSERVERNAME].[AdventureWorks2008].dbo.sp_executesql @sql
profiler跟蹤到的語句如下:
如有不對的地方,歡迎拍磚;如有其他方法,求分享,謝謝!