Sql-Server
SQL Server 更新語句加入索引列
使用 SQL Server 2012,我有一個儲存過程,它通過執行類似於以下的刪除和插入來更新數據:
DELETE FROM MyTable WHERE EXISTS ( SELECT 1 FROM StagingMyTable s WHERE MyTable.ID = s.ID AND MyTable.ID2 = s.ID2) INSERT INTO MyTable SELECT * FROM StagingMyTable
已更改為更新和插入過程,如下所示:
UPDATE mt SET mt.ID = s.ID , mt.ID2 = s.ID2 , mt.col1 = s.col1 , mt.col2 = s.col2 /* Rest of the columns here*/ FROM MyTable mt JOIN StagingMyTable s ON mt.ID = s.ID and mt.ID2 = s.ID2 INSERT INTO MyTable SELECT * FROM StagingMyTable s WHERE NOT EXISTS ( SELECT 1 FROM MyTable WHERE MyTable.ID = s.ID AND MyTable.ID2 = s.ID2)
MyTable 在 ID 和 ID2 列上有一個聚集索引,這就是我們決定更新儲存過程以更新和插入的原因。我想知道的是我是否應該在更新語句中省略兩個關鍵列,即使這些值沒有被更改,即
UPDATE mt SET mt.col1 = s.col1 , mt.col2 = s.col2 /* Rest of the columns here*/ FROM MyTable mt JOIN StagingMyTable s ON mt.ID = s.ID and mt.ID2 = s.ID2
如果我在更新語句中包含鍵列,SQL Server 是否認為這些將是新值並刪除並重新插入行?
SQL Server 可能會根據許多因素選擇執行就地更新或插入和刪除,您不必擔心。由於沒有更新密鑰,我會將它們排除在 SET 子句之外,以幫助優化器做出最佳決策。
如果您使用的是 SQL Server 2008 或更高版本,請查看可以替換這兩個操作的 MERGE 語句: https ://docs.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view =sql-server-2017
高溫高壓
如果
ID and ID2
列是關鍵列,那麼您需要擔心錯誤的更新語句。同意,
those values aren't being changed
但它創建了非常昂貴的查詢計劃。事實上,您應該
mt.col1 = s.col1 , mt.col2 = s.col2
在 Update your Self 中比較有無查詢計劃。Begin Tran UPDATE mt SET mt.col1 = s.col1 , mt.col2 = s.col2 /* Rest of the columns here*/ FROM MyTable mt JOIN StagingMyTable s ON mt.ID = s.ID and mt.ID2 = s.ID2 If (@@TranCount>0) RollBack
您會注意到拆分運算符,它是 拆分排序折疊模式的一部分
如果我在更新語句中包含鍵列,SQL Server 是否認為這些將是新值並刪除並重新插入行?
是的,這樣
Execution plan
顯示split-sort-collapse
。執行計劃中有一個操作員完全相同(刪除並重新插入行)。