Skip to content

sql-truncate-table-command

TRUNCATE TABLE 命令是一种数据定义语言(Data Definition Language, DDL)语句,用于快速高效地删除表中的所有行。虽然它的效果与不带 WHERE 子句的 DELETE 语句相似,但其底层机制却大相径庭。

与删除表结构本身的 DROP TABLE 不同,TRUNCATE TABLE 会保留表结构,包括列、约束和索引,使其可用于存储新数据。

TRUNCATE TABLE 命令的基本语法是:

TRUNCATE TABLE table_name;

某些关系型数据库管理系统(RDBMS)提供了扩展语法。例如,在 PostgreSQL 中,你还可以重置关联的序列并管理外键依赖:

-- PostgreSQL 示例
TRUNCATE TABLE table_name RESTART IDENTITY CASCADE;
  • 性能: TRUNCATE 对于大型表来说速度显著更快,因为它会解除分配数据页,而不是逐行删除记录。
  • 日志: TRUNCATE 的日志记录量很小,而 DELETE 则会记录每一行删除操作,这可能会产生大量的事务日志数据。
  • 触发器: 在大多数数据库中,TRUNCATE 不会触发 DELETE 触发器。DELETE 会为每个受影响的行触发器。
  • 标识列: TRUNCATE 会将标识列(自增列)重置为其起始值。DELETE 不会。
  • 事务: DELETE 是一种数据操作语言(Data Manipulation Language, DML)操作,并且总是可以回滚。TRUNCATE 是一种 DDL 操作;它是否能回滚取决于 RDBMS(在 PostgreSQL 和 SQL Server 中可以,但在旧版 MySQL 中是隐式提交)。

假设有一个累积了大量记录的 Logs 表:

+----+------------+-----------------------------------+
| ID | LogLevel | Message |
+----+------------+-----------------------------------+
| 1 | INFO | User 'alice' logged in. |
| 2 | INFO | User 'bob' logged in. |
| 3 | WARNING | Disk space is running low. |
|... | ... | ... (millions of other rows) |
+----+------------+-----------------------------------+

要清除此表以开始一个新周期,使用 DELETE FROM Logs; 会非常慢。TRUNCATE 命令是理想的解决方案:

TRUNCATE TABLE Logs;

执行此命令后,Logs 表将变为空,并且如果其 ID 列是标识列/自增列,则插入的下一条记录将从 1(或其原始种子值)开始。

SELECT * FROM Logs;
-- 返回:空集

当你需要删除表中所有数据、不需要触发触发器且性能是主要考虑因素时,请使用 TRUNCATE TABLE。它在数据仓库(ETL 过程)中以及在测试或开发环境中重置表时是一种常见的操作。