TRUNCATE TABLE 是什么
TRUNCATE TABLE 清空整张表,比 DELETE 快得多:它不做逐行删除与行级日志,本质上是重建表(InnoDB 实际是丢弃旧表空间并新建同名表)。代价也很明确:不支持 WHERE,MySQL 下属于 DDL、会隐式提交且无法回滚,自增计数会被重置。PostgreSQL 的 TRUNCATE 是事务型的,可以回滚,还支持 RESTART IDENTITY 重置序列、CASCADE 连带清空引用它的表。外键、权限与锁等级都要在使用前确认。
基本信息
| 适用平台 | MySQL 8.0 / PostgreSQL / SQL Server / Oracle |
|---|---|
| MySQL 语义 | DDL,隐式提交、不可回滚;自增计数重置为 1 |
| PostgreSQL 语义 | 事务内可回滚;RESTART IDENTITY 重置序列、CASCADE 连带清空 |
| 外键限制 | MySQL 有外键引用时直接报错 1701;PG 需 CASCADE 或同时列出被引用表 |
| 权限要求 | MySQL 需要对表的 DROP 权限(等价于重建表) |
| 空间回收 | 两库都会立即释放空间,不像 DELETE 需要后续清理 |
典型使用场景
- 测试与开发环境重置数据,快速回到干净状态
- 日志表、临时表、中间结果表的定期清空
- 重新导入前的清场:先清空再批量导入
- ETL 全量刷新:目标表每天重建一次
- 分区表清理:多数场景用 DROP PARTITION 比 TRUNCATE 更合适
两库写法差异
两库写法差异
-- MySQL:DDL 语义,会隐式提交,无法回滚
TRUNCATE TABLE logs;
-- 执行前确认表大小,避免对超大表误操作
SELECT table_rows, data_length FROM information_schema.tables
WHERE table_schema = DATABASE() AND table_name = 'logs';PostgreSQL 事务用法
PostgreSQL 事务用法
BEGIN;
TRUNCATE TABLE logs RESTART IDENTITY; -- 同时把自增序列重置为 1
COMMIT; -- PG 里 TRUNCATE 可回滚,出错时可 ROLLBACK
-- 有外键引用时,同时列出相关表或用 CASCADE
TRUNCATE TABLE orders, order_items RESTART IDENTITY;
TRUNCATE TABLE orders CASCADE; -- 会连带清空引用它的表,谨慎使用与 DELETE 的关键差异
| 对比项 | TRUNCATE | DELETE |
|---|---|---|
| 过滤条件 | 不支持 WHERE | 支持 WHERE |
| 回滚能力 | MySQL 不可回滚;PG 可回滚 | 可回滚 |
| 自增计数 | 重置 | 不重置 |
| 日志量 | 极少(不逐行记录) | 逐行记录,量大 |
| 触发器 | 不激活 | 激活 DELETE 触发器 |
| 锁 | 需要高等级锁,可能短暂阻塞写入 | 行级锁 |
MySQL 中 TRUNCATE 需要表的 DROP 权限,因为实现上等于重建表;只授予了 DELETE 权限的账号执行会报权限错误,而 DELETE 语句本身可以正常执行。
生产环境执行前确认三件事:有没有外键引用、有没有应用正在写入、自增计数是否需要保留。TRUNCATE 无法回滚,误执行的代价与 DROP TABLE 接近。