mysql 8.0.24+ 仅支持对 range/list 分区执行 truncate table ... partition,key/hash 分区不支持;该操作为 ddl,不可回滚、重置自增、绕过触发器,且需 alter 权限和表级 mdl 锁。

MySQL 8.0+ 支持 TRUNCATE TABLE ... PARTITION,但有严格前提
直接执行 TRUNCATE TABLE t1 PARTITION (p2) 会失败,除非表是 **LIST 或 RANGE 分区**,且你用的是 MySQL 8.0.24 及以上版本。MySQL 5.7 和早期 8.0 版本根本不支持该语法,只会报错 ERROR 1064 (42000): You have an error in your SQL syntax。
关键判断点:先查分区类型和 MySQL 版本:
SELECT VERSION();<br>SELECT PARTITION_NAME, PARTITION_METHOD FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'your_db';
- 如果是
KEY或HASH分区 →TRUNCATE ... PARTITION语法无效,必须换方案 - 如果是
RANGE/LIST且版本 ≥ 8.0.24 → 可用,但需注意权限和锁行为 - 即使语法合法,执行时仍可能被阻塞:该操作需要
ALTER权限,且会获取表级元数据锁(MDL),期间其他 DDL 会被挂起
TRUNCATE PARTITION 和 DELETE FROM ... WHERE 的实际差异
很多人以为 TRUNCATE PARTITION 就是“更快的 DELETE”,但本质完全不同:前者是 DDL,后者是 DML。这意味着:
-
TRUNCATE PARTITION不走事务日志(不写 undo log),无法回滚;DELETE在事务中可回滚 -
TRUNCATE PARTITION会重置该分区的自增计数器(如果该分区含AUTO_INCREMENT列);DELETE不影响 -
DELETE走索引、触发器、外键检查;TRUNCATE PARTITION绕过所有这些,只清空物理段 - 性能上:对亿级分区,
TRUNCATE PARTITION是毫秒级;DELETE即使带分区剪枝(WHERE dt = '2023-01'),也可能因索引扫描和 binlog 写入慢几秒到几分钟
替代方案:当 TRUNCATE PARTITION 不可用时,用 DROP PARTITION + REORGANIZE
对 KEY/HASH 分区或老版本 MySQL,唯一接近“清空单分区”的做法是先删分区再重建——但仅适用于可预知范围的 RANGE/LIST 表。例如原表按月分区:
ALTER TABLE t1 DROP PARTITION p202301;<br>ALTER TABLE t1 REORGANIZE PARTITION p202302 INTO (<br> PARTITION p202301 VALUES LESS THAN (UNIX_TIMESTAMP('2023-02-01')),<br> PARTITION p202302 VALUES LESS THAN (UNIX_TIMESTAMP('2023-03-01'))<br>);
- 这组操作等价于“清空 p202301 并保留结构”,但要求新旧分区边界能无缝衔接
- 不能用于
HASH分区:因为DROP PARTITION不被允许 - 风险高:若
REORGANIZE边界算错,会导致数据误入其他分区,务必在测试库验证EXPLAIN PARTITIONS SELECT * FROM t1 WHERE dt = '2023-01-15'
最容易被忽略的点:分区名大小写和引号
分区名在 MySQL 中默认是**大小写敏感**的,且不能用反引号包裹(否则语法报错)。比如:
- ✅ 正确:
TRUNCATE TABLE t1 PARTITION (p202301); - ❌ 错误:
TRUNCATE TABLE t1 PARTITION (`p202301`);→ 报ERROR 1064 - ❌ 错误:
TRUNCATE TABLE t1 PARTITION (P202301);→ 若建表时写的是小写p202301,则找不到分区 - 查分区名最稳妥方式:
SELECT PARTITION_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' ORDER BY PARTITION_ORDINAL_POSITION;
另外,分区名里若有特殊字符(如连字符),必须用单引号,例如 PARTITION ('p-2023-01') —— 这点文档极少提,但实测 8.0.33 确实需要。











