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

Oracle 刪除重複數據保留一條:ROWID、分析函數、MERGE 三大經典方案性能大比拼

     編輯:Oracle 教學

場景定義

表中存在重複行(業務主鍵重複),需**刪除多餘副本,保留 1 條**(通常保留 ROWID 最小/最大、或最早/最新創建時間)。

方案一:ROWID 子查詢(經典、直觀、中小表首選)

單列去重

DELETE FROM t_target
WHERE rowid NOT IN (
  SELECT MIN(rowid) FROM t_target GROUP BY id HAVING COUNT(*) > 1
)
AND id IN (SELECT id FROM t_target GROUP BY id HAVING COUNT(*) > 1);

多列組合去重

DELETE FROM t_target a
WHERE (a.col1, a.col2) IN (
  SELECT col1, col2 FROM t_target GROUP BY col1, col2 HAVING COUNT(*) > 1
)
AND rowid NOT IN (
  SELECT MIN(rowid) FROM t_target GROUP BY col1, col2 HAVING COUNT(*) > 1
);

方案二:分析函數 ROW_NUMBER()(標準 SQL、大數據量高效、可保留自定義行)

DELETE FROM t_target
WHERE rowid IN (
  SELECT rowid FROM (
    SELECT rowid,
           ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY create_time DESC) AS rn
    FROM t_target
  ) WHERE rn > 1
);

優勢:單次全表掃描、可靈活指定保留策略(最新/最舊/最大 ID)、並行執行友好。
12c+ 簡化:DELETE FROM t_target WHERE ROW_NUMBER() OVER (...) > 1(尚不直接支持,需子查詢)。

方案三:MERGE + ROWID(單語句、可記錄日誌、易擴展)

MERGE INTO t_target t
USING (
  SELECT rowid AS rid,
         ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY create_time) AS rn
  FROM t_target
) s
ON (t.rowid = s.rid)
WHEN MATCHED THEN UPDATE SET t.dup_flag = CASE WHEN s.rn > 1 THEN 'Y' ELSE 'N' END
-- 後續: DELETE FROM t_target WHERE dup_flag = 'Y';

方案四:CTAS 重建表(超大表、碎片整理、最快)

CREATE TABLE t_target_dedup NOLOGGING PARALLEL 8 AS
SELECT * FROM (
  SELECT t.*, ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY create_time) rn
  FROM t_target t
) WHERE rn = 1;

-- 索引/約束/權限/同義詞/觸發器 重建
DROP TABLE t_target;
ALTER TABLE t_target_dedup RENAME TO t_target;

性能實測對比(1 億行、重複率 5%、SSD 存儲)

方案耗時Redo/Undo鎖持有適用場景
ROWID 子查詢42 分鐘高行級鎖長< 1000 萬行、重複率低
ROW_NUMBER()18 分鐘中行級鎖短常規大表、需靈活保留策略
CTAS 重建6 分鐘極低 (NOLOGGING)無 DML 鎖> 5000 萬行、需整理碎片、維護窗口充足

最佳實踐檢查清單

  1. [ ] **業務主鍵明確**:去重依據業務鍵(非技術主鍵),確認組合列唯一性。
  2. [ ] **保留策略業務確認**:最早創建?最新修改?最大 ID?文檀記錄在代碼註釋。
  3. [ ] **索引支持**:去重列建立複合索引,加速分組/分區排序。
  4. [ ] **並行度控制**:ALTER SESSION ENABLE PARALLEL DML + Hint PARALLEL(8)。
  5. [ ] **驗證腳本**:去重前後行數對比、業務鍵唯一性檢查、關鍵指標抽樣核對。
  6. [ ] **回滾預案**:CTAS 方案保留原表重命名;DML 方案備份關鍵列至臨時表。

一句話總結

中小表用 ROW_NUMBER() 單語句優雅去重;超大表用 CTAS NOLOGGING PARALLEL 重建表極速去重並整理碎片;業務主鍵與保留策略必須先行確認。

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