MySQL 中 truncate 和 delete 的坑
truncate 和 delete 是 MySQL 中清空表資料的兩種方式,平常使用的時候兩者好像都差不多,選誰都可以。實際上它們之間是有本質區別的,只有深入理解了它們的差異,在以後的開發中才能根據具體場景運用自如
思考
在講 truncate 和 delete 的區別之前,不妨先看看下面的問題,帶著問題邊思考邊往下看
問題:如上圖所示,紅色框(1) 和 紅色框(2) 中 id 分別是多少
delete 簡述
刪除表全部資料或者部分資料,刪除的時候是一行一行刪除的,所以刪除表全部資料時速度比較慢
語句後面可以用 where 過濾待刪除的行,比較靈活
語句執行之後會返回本次刪除的行數
truncate 簡述
刪除表全部資料,相當於先 drop table 然後 create table, 速度快
語句後面不能接過濾條件
語句執行後沒有返回值,或者說返回值沒有具體的含義
區別
雖然 truncate 和 delete 很相似,但它們有以下不同之處
-
delete 是一行一行的刪除資料,truncate 是重新建立表,所以truncate 比 delete 速度快,特別是針對大表
-
其他表有引用本表列的外來鍵時,truncate 會執行失敗,delete 可以執行
上圖中 tb
表的 idb
列是ta
表的ida
列的外來鍵引用,truncate table ta
執行失敗, ``delete from ta```能執行成功
-
truncate 是DDL語句,所以不能回滾,delete 是DML語句,可以回滾
-
truncate 返回值無意義, delete 返回本次刪除的行數
-
針對 AUTO_INCREMENT 列,truncate tablename 會把列值重置為起始值,而 delete from tablename 則不會重置(上面的思考題用到了這條知識點)
delete 的優化
前面提到使用 delete 清空大表是速度比較慢,為了保證 delete 語句不會佔用大量的時間,可以使用 limit row_count
語句來指定單次刪除的最大行數,如果刪除的行數大於等於單次刪除的最大行數,重複執行 delete 語句直到刪除的行數小於單次刪除的最大值
答案
有了前面的介紹之後,思考題的答案應該很清晰了
因為表 tt
中 id
列是自增的,truncate 清空表資料會重置自增列,而 delete則不會,所以思考題中 (1) 處的 id 分別是 3、4, (2) 處的 id 分別是 1,2
具體的輸出如下圖: