首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 刪數據:DELETE 與 TRUNCATE 深度對比與選型

     編輯:MySQL 資料庫相關知識

核心差異一覽

維度DELETETRUNCATE
語法類型DMLDDL
執行機制逐行刪除,記錄 Binlog(ROW 格式每行一條)釋放數據頁,重建表結構,最少 Binlog
速度慢(大表極慢)極快(元數據操作)
事務安全支持回滾隱式提交,不可回滾
觸發器觸發 FOR EACH ROW不觸發
自增 ID保持不變重置為 1(或初始值)
外鍵約束檢查並報錯/級聯若被引用則報錯(需先刪 FK)
空間回收不釋放磁盤空間(標記刪除)釋放數據頁歸還表空間
WHERE 支持支持不支持
權限需求DELETE 權限DROP 權限

典型場景選型


-- 1. 清空全表、重置自增 ID、釋放空間 → TRUNCATE
TRUNCATE TABLE logs;

-- 2. 保留自增 ID、需回滾、有觸發器/外鍵 → DELETE
DELETE FROM orders WHERE status = 'cancelled';

-- 3. 大表分批刪除(避免長事務、鎖升級、主從延遲)
-- 建議:每批 5000~10000 行,間隔 SLEEP
WHILE (SELECT COUNT(*) FROM big_tbl WHERE dt < '2023-01-01') > 0 DO
    DELETE FROM big_tbl WHERE dt < '2023-01-01' LIMIT 5000;
    DO SLEEP(0.5);
END WHILE;

-- 4. 分區表快速清理歷史分區
ALTER TABLE big_tbl DROP PARTITION p_202201;

InnoDB 大表 DELETE 性能優化

  1. 按主鍵順序刪除:減少頁分裂、Undo Log 體積
  2. 使用索引覆蓋:WHERE indexed_col = val 避免全掃
  3. 調大 innodb_buffer_pool_size:減少磁盤 IO
  4. 臨時設 innodb_flush_log_at_trx_commit=2:批量刪除期間犧牲 1s 數據安全換吞吐

TRUNCATE 陷阱

  • MySQL 5.7+ TRUNCATE 會獲取 MDL 排他鎖,阻塞並發 DDL/DML
  • 若表被 FOREIGN KEY 引用,必須先 ALTER TABLE child DROP FOREIGN KEY fk_name
  • 復制環境下 TRUNCATE 以 STATEMENT 格式寫 Binlog,從庫同步極快

總結口訣


全表清空要快用 TRUNCATE,帶條件刪改用 DELETE;
自增歸零釋放空間 TRUNCATE,事務回滾觸發器 DELETE;
大表分批刪除要有度,主鍵順序索引覆蓋最優秀。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved