MySQL删除表、清空表,truncate和delete区别
前言
清空表数据,用DELETE还是TRUNCATE?删表用DROP?很多人搞混,本文讲清楚区别。
三种操作
1. DELETE:删行
-- 删指定行
DELETE FROM users WHERE id = 1;
-- 删全表
DELETE FROM users;
特点:
- 一行一行删,慢
- 可以加WHERE条件
- 可以回滚(在事务里)
- 自增ID不重置,继续从之前的数开始
- 会写binlog
2. TRUNCATE:清空表
TRUNCATE TABLE users;
特点:
- 直接删表重建,快
- 不能加WHERE条件
- 不能回滚
- 自增ID重置,从1开始
- 比DELETE快很多
3. DROP:删表
DROP TABLE users;
特点:
- 表结构+数据全删
- 表都没了
- 最快
对比表
| 对比项 | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| 删什么 | 删行 | 删表重建 | 删表 |
| 速度 | 慢 | 快 | 最快 |
| WHERE | 支持 | 不支持 | 不支持 |
| 回滚 | 可以 | 不可以 | 不可以 |
| 自增ID | 不重置 | 重置 | 表都没了 |
| 表结构 | 保留 | 保留 | 删除 |
| 写binlog | 是 | 是(默认) | 是 |
什么时候用哪个
用DELETE
- 只删部分数据(带WHERE)
- 需要回滚
- 数据量小
用TRUNCATE
- 清空全表数据
- 数据量大,要快
- 不需要回滚
用DROP
- 表不要了
- 表结构也删
常见坑
坑1:DELETE删全表很慢
DELETE FROM users;
100万行删半天。
解决: 清空全表用 TRUNCATE TABLE users;
坑2:TRUNCATE不能回滚
执行TRUNCATE后想后悔,回不去了。
解决: 执行前先备份,或者用DELETE(慢但能回滚)。
坑3:TRUNCATE自增ID重置
清空表后,自增ID从1开始了。
原因: TRUNCATE会重建表。
解决: 如果不想重置自增ID,用DELETE。
坑4:外键约束导致TRUNCATE失败
ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint
原因: 有其他表的外键关联到这个表。
解决: 先关外键检查:
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE users;
SET FOREIGN_KEY_CHECKS = 1;
坑5:DELETE不写WHERE删全表
手滑了,没写WHERE,把全表删了。
解决: 执行DELETE前,先SELECT一下看条件对不对。
性能对比
| 操作 | 10万行 | 100万行 |
|---|---|---|
| DELETE全表 | 几十秒 | 几分钟 |
| TRUNCATE | 0.01秒 | 0.01秒 |
| DROP | 0.01秒 | 0.01秒 |
TRUNCATE和DROP都是秒级,DELETE要逐行删。
总结
一句话总结:
- 删部分数据 → DELETE
- 清空全表 → TRUNCATE
- 表不要了 → DROP
记住: 清空表别用DELETE,太慢了。
遇到问题加QQ23979811 协助处理