刪除表中全部資料時,DELETE 與 TRUNCATE 效能差距可達數十倍。本文從執行機制、空間釋放、觸發器、高水位線 (HWM)、恢復機制、實測數據六大維度深度對比,助你選擇正確工具。
| 維度 | DELETE | TRUNCATE |
|---|---|---|
| 執行類型 | DML(逐列處理) | DDL(段級操作) |
| 事務控制 | 需 COMMIT/ROLLBACK | 隱含 COMMIT,不可回滾 |
| 觸發器 | 觸發 BEFORE/AFTER DELETE FOR EACH ROW | **不觸發**任何 DML 觸發器 |
| High Water Mark | 不下降,空間不釋放 | **重置為 0**,瞬間釋放段空間 |
| Undo/Redo 量 | 大量(每列記錄) | 極少(僅記錄資料字典變更) |
| 索引/約束 | 維護索引、檢查 FK | 索引變 UNUSABLE(需 REBUILD)、FK 必須先停用 |
| 權限需求 | DELETE 物件權限 | DROP TABLE 系統權限或擁有者 |
| 閃回恢復 | FLASHBACK TABLE ... TO BEFORE DROP 不適用 | 無法閃回,**永久刪除** |
| WHERE 條件 | 支援 | **不支援**(12c+ 可用 TRUNCATE TABLE ... PARTITION) |
-- DELETE
DELETE FROM users WHERE userid = '001'; -- 條件刪除
DELETE FROM users; -- 全表刪除(極慢)
-- TRUNCATE
TRUNCATE TABLE users; -- 預設 DROP STORAGE,釋放空間
TRUNCATE TABLE users REUSE STORAGE; -- 保留段空間(HWM 不動),下次插入更快
TRUNCATE TABLE users DROP ALL STORAGE; -- 12c+ 釋放所有分區段空間
INSERT 4,194,304 列 → DELETE 耗時 90.96 秒
INSERT 8,388,608 列 → TRUNCATE 耗時 2.22 秒
效能差距 > 40 倍
測試環境:單機、無索引、無觸發器、預設 Undo/Redo 設定。實際生產環境差距隨索引、觸發器、FK、Undo 保留而擴大。
DBMS_AUDIT/CDC)ALTER TABLE child DISABLE CONSTRAINT fk → TRUNCATE 父表 → ENABLE CONSTRAINTALTER INDEX ... REBUILD 或 ALTER INDEX ... REBUILD ONLINETRUNCATE TABLE ... PARTITION (p_202401) (12c+)| 誤區 | 事實 |
|---|---|
| TRUNCATE 可 Rollback | DDL 隱含 COMMIT,**不可回滾** |
| TRUNCATE 不產生 Redo | 產生極少 Redo(資料字典變更),非零 |
| DELETE 後空間自動釋放 | HWM 不動,**必須 TRUNCATE 或 ALTER TABLE ... MOVE + REBUILD INDEX** |
| TRUNCATE 速度快是因為不寫 Redo | 主因是段級操作、不逐列處理、不維護索引鍵、不檢查 FK |
TRUNCATE 是 DBA 清理測試資料、重置分區、ETL 暫存表清空的利器;DELETE 是業務邏輯刪除的標準工具。**場景選對工具,效能差百倍**。