缺乏主鍵/唯一約束、ETL 重複載入、應用邏輯缺陷導致重複行。佔用空間、干擾統計資訊、導致查詢結果錯誤,需定期清理。
DELETE FROM tb_channel a
WHERE a.rowid IN (
SELECT MAX(b.rowid)
FROM tb_channel b
WHERE a.policyno = b.policyno
AND a.classcode = b.classcode
);
-- 1. 建立去重臨時表
CREATE TABLE temp_emp AS SELECT DISTINCT * FROM employee;
-- 2. 清空原表(TRUNCATE 釋放高水位,極快)
TRUNCATE TABLE employee;
-- 3. 插回去重資料
INSERT INTO employee SELECT * FROM temp_emp;
-- 4. 重建索引、約束、授權(TRUNCATE 會移除)
-- 5. 統計資訊收集
DROP TABLE temp_emp;
-- Oracle 不支援 SELECT INTO 新表,需用 CTAS
CREATE TABLE new_table AS SELECT DISTINCT * FROM old_table;
-- 刪除舊表
DROP TABLE old_table;
-- 重命名(需權限)
RENAME new_table TO old_table;
-- 或使用 DBMS_REDEFINITION 線上重定義(零停機)
| 維度 | ROWID 刪除 | 臨時表換入 | CTAS 重建 |
|---|---|---|---|
| 適用資料量 | < 10 萬行 | 任意大表 | 任意大表 |
| 執行速度 | 慢 | 快 | 最快 |
| Undo 產生 | 大 | 極小 | 極小 |
| 鎖表時間 | 長 | 短 | 短 |
| 索引/約束保留 | 自動保留 | 需手工重建 | 需手工重建 |
| 線上業務影響 | 高 | 高(需窗口) | 高(需窗口) |
| 零停機選項 | 無 | DBMS_REDEFINITION | DBMS_REDEFINITION |
DBMS_STATS.GATHER_TABLE_STATS,否則優化器誤判導致效能倒退。