Sql-Server

刪除和插入性能 SQL Server

  • January 7, 2018

我有以下儲存過程,需要將近一個小時才能完成。結果集大約是 200K 機器。

我所做的只是從連結伺服器中提取一組 id,在本地伺服器中刪除這些 id,然後從遠端伺服器中提取這些 id 的所有詳細資訊並插入它們。INSERT 佔 90%,DELETE 表佔 9%,SELECT INTO 佔 1%。

id 是主鍵/聚集索引。

   DECLARE @ProcessDate DATETIME
   SET @ProcessDate = CONVERT(VARCHAR(10), DATEADD(DAY, -3,
                                                   GETDATE()), 111)

   SELECT  DISTINCT id
   INTO    #temp_machines
   FROM    remote_server.db.dbo.table1
   WHERE   dt_modify >= @ProcessDate

   DELETE  FROM local_server.db.dbo.table2
   WHERE   id IN ( SELECT id  FROM  #temp_machines )

   INSERT  INTO local_server.db.dbo.table2
   SELECT  *
   FROM    remote_server.db.dbo.table1
   WHERE   id IN ( SELECT id  FROM  #temp_machines )

關於提高性能的任何建議?

**第一步:**確保有一些東西需要調整,並且您的查詢不只是被阻止。您可以使用sp_WhoIsActivesp_BlitzFirst等免費工具來執行此操作(免責聲明,我是 First Responder Kit 的貢獻者)。

**第二步:**不要使用局部變數

**第三步:**也許索引臨時表會有所幫助。

第四步:使用 sp_BlitzFirst 檢查您的等待統計資訊(關於我對此做出貢獻的相同免責聲明,等等等等)。可能是編寫的查詢很好,但是您遇到了其他問題,例如 tempdb 爭用。

假設您所說的“遠端伺服器”是指連結伺服器(或至少類似的東西),那麼一個潛在的問題是您正在對相當於相同數據的內容進行兩次查詢。此外,通過使用,您可能會強制伺服器每行IN (SELECT ...)重新執行一次該語句。SELECT

我會嘗試以下方法:

DECLARE @ProcessDate DATETIME
SET @ProcessDate = CONVERT(VARCHAR(10), DATEADD(DAY, -3,
                                               GETDATE()), 111)

SELECT  *
INTO    #temp_machines
FROM    table1
WHERE   dt_modify >= @ProcessDate

DELETE  t2
FROM    table2 t2
         INNER JOIN (SELECT DISTINCT id FROM #temp_machines) tm ON (t2.id = tm.id)

INSERT  INTO table2
SELECT  *
FROM    #temp_machines

畢竟,您將table1在某個時候將所有匹配數據從本地數據庫中提取出來;把它放在前面,你可以在剩下的查詢中忽略遠端伺服器。

更好的是,如果table1.id是唯一的或主鍵,您DELETE可以:

DELETE  t2
FROM    table2 t2
         INNER JOIN #temp_machines tm ON (t2.id = tm.id)

即使table1.

引用自:https://dba.stackexchange.com/questions/194558