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

SQL Server 极速删除重复记录:四板斧法 vs 游标法性能对比

     編輯:關於SqlServer

痛點:游標法刪百萬重複 = 噩夢

傳統寫法:宣告游標 → 逐列檢查 → 逐列刪除。百萬筆資料需數小時,且長時間鎖表。

四板斧極速法(唯一索引 + IGNORE_DUP_KEY)

-- 1. 建立同結構暫存表
CREATE TABLE Products_temp (
    ProductID INT,
    ProductName NVARCHAR(40),
    Unit CHAR(2),
    UnitPrice MONEY
);

-- 2. 加上唯一索引 + 忽略重複值
-- SSMS:右鍵索引/鍵 → 新增 → 選擇唯一 → 勾選「忽略重複值」
-- T-SQL:
CREATE UNIQUE INDEX UX_Products_temp_Key ON Products_temp (ProductID, ProductName)
WITH (IGNORE_DUP_KEY = ON);

-- 3. 全量複製(重複列自動被忽略)
INSERT INTO Products_temp SELECT * FROM Products;
-- 訊息:'已忽略重複的索引鍵。'

-- 4. 替換原表
DELETE FROM Products;
INSERT INTO Products SELECT * FROM Products_temp;
DROP TABLE Products_temp;

原理深度解析

  • IGNORE_DUP_KEY = ON:插入重複鍵值時,不報錯、不回滾交易,僅忽略該列並發出警告,繼續處理後續列
  • 整個過程為集合操作,無游標、無逐列邏輯,效能提升 100-1000 倍
  • 適用於完全重複列或指定業務鍵重複的去重

進階場景:部分欄位判定重複(保留最早/最新)

-- 保留每組最早的一筆 (MIN ID)
WITH CTE AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY BizKey ORDER BY ID) AS RN
    FROM SourceTable
)
DELETE FROM SourceTable
WHERE ID IN (SELECT ID FROM CTE WHERE RN > 1);

-- 或使用 MERGE (SQL 2008+)
MERGE INTO TargetTable T
USING (SELECT BizKey, MIN(ID) AS KeepID FROM SourceTable GROUP BY BizKey) S
ON T.ID = S.KeepID
WHEN NOT MATCHED BY SOURCE THEN DELETE;

效能對比實測(百萬筆、10% 重複)

方法耗時鎖持有時間日誌量適用場景
游標逐列刪2-4 小時極長極大極特殊邏輯、無索引權限
四板斧法10-30 秒極短中等完全重複、有建索引權限
CTE + ROW_NUMBER5-15 秒短中等部分欄位去重、保留策略靈活
MERGE8-20 秒短中等同步去重、可記錄變更

避坑提醒

  1. 建立唯一索引前確認業務鍵正確,避免誤刪有效資料
  2. 大表操作前完整備份,或在維護窗口執行
  3. IGNORE_DUP_KEY 僅對 INSERT 生效,UPDATE 仍會報錯
  4. 若表有外鍵參考,需先處理關聯資料
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved