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

SQL Server 百萬級數據秒級去重:唯一索引法實戰

     編輯:關於SqlServer

游標逐行比對刪除重複記錄在百萬級數據下耗時數小時,不可接受。利用唯一索引忽略重複鍵特性,配合臨時表,僅需四條語句即可秒級完成去重。本文提供標準化操作流程與關鍵注意事項。

核心原理

創建帶 IGNORE_DUP_KEY = ON 的唯一索引,批量插入源表數據時,重複鍵行會被靜默忽略(僅產生告警訊息「已忽略重複的鍵」),不報錯、不回滾,最終得到無重複的臨時表,再覆蓋回源表。

四步走標準流程

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

-- 2. 加唯一索引,忽略重複鍵(關鍵步驟)
CREATE UNIQUE INDEX UX_Products_temp_Dedup
ON Products_temp (ProductName, Unit, UnitPrice)  -- 按業務鍵去重
WITH (IGNORE_DUP_KEY = ON);

-- 3. 批量複製數據,重複行自動過濾
INSERT INTO Products_temp SELECT * FROM Products;
-- 訊息:已忽略重複的鍵。

-- 4. 覆蓋回源表
TRUNCATE TABLE Products;          -- 比 DELETE 更快、不記錄日誌
INSERT INTO Products SELECT * FROM Products_temp;
DROP TABLE Products_temp;

關鍵決策點:業務鍵如何選?

  • 去重依據 = 唯一索引鍵列。必須與業務「唯一性定義」完全一致。
  • 例:同一產品名、單位、單價視為重複 → 索引建在 (ProductName, Unit, UnitPrice)。
  • 若包含 ProductID(主鍵/身份列),則每行必然唯一,去重失效。

效能對比(百萬級測試)

方法耗時日誌量備註
游標循環刪除數小時極大逐行操作、大量鎖、日誌暴增
CTE + ROW_NUMBER() 刪除數分鐘大需排序、Tempdb 壓力大
唯一索引法秒級極小批量操作、最小日誌、無排序

避坑指南

  1. 確認業務鍵:與業務方二次確認去重維度,防誤刪有效數據。
  2. 大表分批:若表極大(億級),分時間窗/主鍵範圍分批處理,避免長事務鎖表。
  3. 外鍵/觸發器:操作前禁用外鍵檢查(ALTER TABLE ... NOCHECK CONSTRAINT ALL)與觸發器,完畢重啟。
  4. IGNORE_DUP_KEY 限制:僅對唯一索引生效,主鍵/非唯一索引不支援;不適用於記憶體優化表。
  5. 備份先行:操作前務必全備份或快照,提供回滾點。

進階:保留「首條/末條」記錄

若需保留最早/最晚插入的記錄(而非隨機保留),先按業務鍵 + 時間排序插入臨時表:

INSERT INTO Products_temp
SELECT * FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY ProductName, Unit, UnitPrice ORDER BY CreateTime) AS rn
    FROM Products
) t WHERE rn = 1;

再按上述流程覆蓋回源表。

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