truncate 耗时吗

TRUNCATE耗时1 000秒是Oceanbase中的一个常见问题。
分区表操作最多可能需要 1 5 分钟。
主要原因是事务日志写入和表锁定。

外键约束检查触发全表扫描。
触发器需要更长的时间来执行。
存储引擎需要释放数据页并重建索引。

优化:删除外键和触发器。
深夜挂着。
监控慢查询日志。
升级OceanBase 4 .x版本。

提醒:执行前请确认不存在依赖约束。

drop、truncate和delete有哪些区别?

说实话,在数据库行业工作了这么多年,DROP、TRUNCATE、DELETE这三个命令实在是让人又爱又恨的话题。
想一想,刚入行的时候,每次遇到数据清理的需求,我都非常紧张——生怕一不小心就毁掉了整个数据库。
尤其是像GaussDB这样的大型平台,如果操作不小心,后果可能会很严重。

以 DROP TABLE 为例。
上次我指导客户时,有一个测试场景几乎让我大吃一惊。
凌晨三点,系统突然报错说该表不存在。
我的手颤抖着,走上了跌落台。
结果,一半的集群崩溃了。
说实话,当时我的脸都绿了。
我赶紧加上了IF EXISTS,避免酿成大祸。
所以当我现在教新人的时候,我说的第一句话就是:在你确认之前不要做任何事情。
例如,在GaussDB上执行DROP TABLE IF EXISTS测试,如果该表确实存在,则将其删除;如果不存在,会报错,但不会影响系统。
这种细节确实需要弄清楚。

有趣的是 TRUNCATE TABLE。
我以前在处理十亿级别的数据表时使用过这个命令,速度快得令人难以置信,几秒钟的时间数据就被删除了。
但后来我发现了一个坑:如果表中有触发器,有些版本的GaussDB会直接报错。
我记得当时的测试数据在3 .0版本才修复了这个问题。
因此,在使用 TRUNCATE 之前,最好先在测试中显示 TRIGGER。
为什么这么快?说白了就是绕过事务日志直接进行DDL操作,但缺点是如果表结构出现问题,比如依赖其他对象,就会直接崩溃。
DELETE 命令特别烦人。
我有一个老同事,总是喜欢用DELETE FROM table WHERE id = 1 ,结果因为写错了id而不是ids,删除了3 000条数据。
这类错误在开发环境中可能还好,但在生产线上却可以直接杀人。
所以现在公司规定DELETE必须经过三级审批。
最重要的是,您不必键入 DELETE FROM table LIMIT 1 00。
它一次只会删除一百个项目。
结果,你必须为 1 亿条数据运行数百万次。
上次调试删除数据库的错误,比如删除表的时候,发现有白痴使用了LIMIT,最后把数据库的CPU提高到了2 00%。
另一个陷阱是,如果忘记WHERE条件,比如DELETE FROM table,某些GaussDB版本会触发全表扫描——我见过一个只有5 00MB的测试表,扫描占用了整个节点CPU。
所以现在我教新人DELETE的时候,直接把ORDER BY和GROUP BY列为禁止。

说起实际场景,我见过最离谱的操作是金融客户使用DELETE实现软删除。
他们在users表中添加了一个is_deleted字段,然后业务需要删除的时候就用DELETE FROM users WHERE is_deleted = 1 结果三个月后数据库崩溃了,运维发现表中8 000万位数据全部is_deleted=1 ——原来业务方感觉比TRUNCATE更稳定。
说实话,我当时就笑出了声。
这种用法在某些场景下其实是有用的,但是维护成本非常高。

最后我想说,这些命令不是三言两语就能说清楚的。
我有一位客户在存储过程中使用了 TRUNCATE,这触发了隐藏的依赖约束,并且直接锁定整个数据库。
这种细节只有经历过坑才能了解到。
因此,给新人一些建议:先用SELECT而不是DELETE来测试条件,确认没有问题后再开始。
备份?这不仅仅是说说而已。
我见过的最糟糕的事情是 DBA 在删除表之前忘记备份表。
第二天他就被老板当众训斥,让他怀疑人生。