drop-delete-truncate对比

drop-delete-truncate对比

drop-delete-truncate的对比

背景知识

Tablespace Segment Extent Block

drop delete truncate 对比

他们都是为了删除数据

Delete

deleteDML,执行delete操作时,DELETE语句执行删除的过程是一行一行的删除表中的数据,并且同时将该行的的删除操作记录在redoundo表空间中以便进行回滚rollback和重做操作,但要注意表空间要足够大,需要手动提交commit操作才能生效,可以通过rollback撤消操作。

delete语句不影响表所占用的extent,高水线high watermark保持原位置不变。

Truncate

  • TRUNCATE TABLE则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。

    并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。 但是有一些关于数据库的触发器会被触发

truncate会删除表中所有记录,并且将重新设置高水线和所有的索引,缺省情况下将空间释放到minextentsextent,除非使用reuse storage。不会记录日志,所以执行速度很快,但不能通过rollback撤消操作(如果一不小心把一个表truncate掉,也是可以恢复的,只是不能通过rollback来恢复)。

TRUNCATE TABLE删除表中的所有行,但表结构及其列、约束、索引等保持不变。

对于外键foreign key约束引用的表,不能使用truncate table,而应使用不带where子句的delete语句。

truncate table不能用于参与了索引视图的表。

OracleMysql中, Truncate Table在是否重置Auto Increment上存在不同: 主要原因是Oracle中使用的是序列Sequence来维持自增长,序列本身不依赖于表,所以并不会重置。

TTRUNCATE TABLE表名 速度快,而且效率高,因为:

虽然TRUNCATE TABLE在功能上与不带WHERE子句的DELETE语句相同:二者均删除表中的全部行。但TRUNCATE TABLEDELETE速度快,且使用的系统和事务日志资源少。

  • DELETE语句每次删除一行,并在事务日志中为所删除的每行记录一项
  • TRUNCATE TABLE通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放

当使用行锁执行DELETE语句时,将锁定表中各行以便删除。TRUNCATE TABLE始终锁定表和页,而不是锁定各行。如无例外,在表中不会留有任何页。

Drop

DropDDL,会隐式提交,所以,不能回滚,不会触发触发器。

Drop语句将表所占用的空间全释放掉。

Drop语句将删除表的结构所依赖的约束,触发器,索引,依赖于该表的存储过程/函数将保留,但是变为invalid状态。

truncatedropDLLdata define language, 操作立即生效,原数据不放到rollback segment中,不能回滚。

总结

  • 在速度上,一般来说,drop > truncate > delete
  • 在使用droptruncate时一定要注意,虽然可以恢复,但为了减少麻烦,还是要慎重。
  • 在没有备份情况下,谨慎使用droptruncate。要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大。

表和索引所占空间

  • Delete:操作不会减少表或索引所占用的空间。
  • Truncate:这个表和索引所占用的空间会恢复到初始大小,
  • Drop:语句将表所占用的空间全释放掉。

如何合理使用这些关键字

  • 如果想删除表,用drop
  • 如果想保留表而将所有数据删除,如果和事务无关,用truncate即可;
  • 如果和事务有关,或者想触发trigger,还是用delete
  • 如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据。

参考文章: