TRUNCATE TABLE 语句
TRUNCATE [TABLE] tbl_name
TRUNCATE TABLE 语句彻底清空表。它须要 DROP 权限。从逻辑上讲,TRUNCATE TABLE 相似于删除全部行的 DELETE 语句,或者是 DROP TABLE 和 CREATE TABLE 语句的组合。
为了实现高性能,TRUNCATE TABLE 绕过了删除数据的 DML 方法。所以,它不会触发 ON DELETE 触发器,不能对具备父-子外键关系的 InnoDB 表执行此命令,也不能像 DML 操做那样回滚。可是,若是服务器在操做期间中止,使用支持原子 DDL 的存储引擎的表上的 TRUNCATE TABLE 操做将被彻底提交或回滚。
虽然 TRUNCATE TABLE 与 DELETE 相似,但它被归为 DDL 语句,而不是DML 语句。与 DELETE 有如下几个不一样之处:
● 截断操做删除并从新建立表,这比逐行删除要快得多,特别是对于大型表。
● 截断操做会致使隐式提交,所以没法回滚。
● 若是会话有生效的表锁定,则没法执行截断操做。
● 对于 InnoDB 或 NDB 表,若是有其余表引用该表的 FOREIGN KEY 约束,TRUNCATE TABLE 命令就会失败。容许在同一表的列之间进行外键约束。
● 截断操做不会返回删除的行数。一般的结果是“0行受影响”,这应该解释为“没有信息”。
● 只要表定义有效,即便数据或索引文件已损坏,也可使用TRUNCATE TABLE 语句将表从新建立为空表。
● 任何 AUTO_INCREMENT 值将被重置为它的初始值。即便对于一般不重用序列值的 MyISAM 和 InnoDB 也是如此。
● 当与分区表一块儿使用时,TRUNCATE TABLE 语句保留分区;也就是说,数据和索引文件被删除并从新建立,而分区定义不受影响。
● TRUNCATE TABLE 语句不会引起 ON DELETE 触发器。
● 支持截断损坏的 InnoDB 表。
对一个表执行 TRUNCATE TABLE 语句,将关闭经过 HANDLER OPEN 对该表打开的全部句柄。
从二进制日志记录和复制的角度看,TRUNCATE TABLE 相似于 DROP TABLE后面紧跟 CREATE TABLE 语句,即 DDL 而不是 DML。这是由于,当使用InnoDB 和其余事务存储引擎时,若是事务隔离级别不容许基于语句的日志记录( READ COMMITTED 或 READ UNCOMMITTED ),则在使用STATEMENT 或 MIXED 日志模式时,不会记录和复制语句。可是,它仍然之前面描述的方式应用于使用 InnoDB 的副本。
在 MySQL5.7 及更早版本中,在一个具备巨大缓冲池和启用innodb_adaptive_hash_index 的系统上,因为删除表的自适应哈希索引项时发生LRU扫描,TRUNCATE TABLE 操做可能会致使系统性能暂时降低。MySQL 8.0中 TRUNCATE TABLE 到 DROP TABLE 和 CREATE TABLE 的从新映射避免了 LRU 扫描的问题。
TRUNCATE TABLE 可用于性能架构摘要表,但其效果是将摘要列重置为 0或 NULL,而不是删除行。
截断独立表空间中的 InnoDB 表,将删除现有表空间并建立一个新表空间。从 MySQL 8.0.21 开始,若是表空间是用早期版本建立的,而且位于一个未知的目录中,InnoDB 会在默认的位置建立新的表空间,并在错误日志中写入以下警告:The DATA DIRECTORY location must be in a known directory. The DATA DIRECTORY location will be ignored and the file will be put into the default datadir location. 已知的目录是由datadir、innodb_data_home_dir 和 innodb_directory 变量定义的目录。要让 TRUNCATE TABLE 在当前位置建立表空间,请在运行 TRUNCATE TABLE以前将目录添加到 innodb_directory 设置中。