首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 關聯表批次 UPDATE 三種寫法效能對比:子查詢、游標、JOIN 更新

     編輯:關於SqlServer

需將 publish 表的 contentid 依 articles 表對應 articleID = objectID 更新。比較三種寫法效能與適用場景。

寫法一:相關子查詢 (單列更新安全,大量更新慢)

UPDATE publish SET contentid = (
    SELECT TOP 1 contentid FROM articles WHERE articleID = publish.objectID
);
  • 每列執行一次子查詢,publish 筆數大時極慢。
  • 若 articles 無對應列,子查詢回傳 NULL → 更新為 NULL (需確認業務允許)。

寫法二:游標逐列更新 (最慢,僅供極複雜邏輯)

DECLARE @contentID INT, @objectID INT;
DECLARE cur CURSOR FOR
SELECT a.contentid, a.articleID FROM publish p
JOIN articles a ON a.articleID = p.objectID
WHERE p.contentid <> a.contentid;
OPEN cur;
FETCH NEXT FROM cur INTO @contentID, @objectID;
WHILE @@FETCH_STATUS = 0 BEGIN
    UPDATE publish SET contentid = @contentID WHERE objectid = @objectID;
    FETCH NEXT FROM cur INTO @contentID, @objectID;
END
CLOSE cur; DEALLOCATE cur;
  • 逐列往返、大量鎖定、記錄檔膨脹,**大量更新嚴禁使用**。

寫法三:JOIN 更新 / FROM 更新 (集合式、最高效)

-- ANSI 標準 (SQL Server 支援)
UPDATE p
SET p.contentid = a.contentid
FROM publish p
JOIN articles a ON a.articleID = p.objectID
WHERE p.cellid = 138;
  • 單一陳述式、集合式運算、最佳化器可產生高效計畫 (Hash Match / Merge Join)。
  • 可加 WHERE 限定範圍、TOP (N) 分批執行避免長交易。

效能對比 (百萬筆模擬)

寫法耗時記錄檔增長鎖定升級風險
子查詢~45 分鐘極大高
游標~2 小時極大極高
JOIN 更新~30 秒適中低

最佳實務

  1. **預設採用 JOIN 更新**,集合思維替代程序思維。
  2. 大量更新加 TOP (10000) 迴圈分批,每批提交、檢查 @@ROWCOUNT。
  3. 更新前建立覆蓋索引 ON articles(articleID) INCLUDE(contentid)、ON publish(objectID) INCLUDE(contentid) 減少鍵查閱。
  4. 若需記錄變更明細,改用 OUTPUT 子句導入稽核表,避免觸發器開銷。

結語

關聯表批次更新,**JOIN 更新 (FROM 更新) 是唯一正解**。子查詢與游標僅適合極少量、極複雜邏輯場景。集合式操作配合分批提交,即可在生產環境安全完成百萬級更新。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved