Home >Database >Mysql Tutorial >Truncate Delete Drop 的区别以及 高水位HWM

Truncate Delete Drop 的区别以及 高水位HWM

WBOY
WBOYOriginal
2016-06-07 17:10:491846browse

Truncate Delete Drop 的区别以及 高水位HWM

truncate操作与delete操作对比

操作

回滚

高水线

空间

效率

Truncate

不能

下降

回收

delete

可以

不变

不回收

相同点:
truncate和不带where子句的delete, 以及drop都会删除表内的数据

 

不同点:
1. truncate和 delete只删除数据不删除表的结构(定义)
    drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger),索引(index); 依赖于该表的存储过程/函数将保留,但是变为invalid状态.
2.delete语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;如果有相应的trigger,执行的时候将被触发.

   truncate,drop是ddl, 操作立即生效,原数据不放到rollback segment中,不能回滚. 操作不触发trigger.

3.delete语句不影响表所占用的extent, 高水线(high watermark)保持原位置不动显然drop语句将表所占用的空间全部释放truncate 语句缺省情况下见空间释放到 minextents个 extent,除非使用reuse storage;   truncate会将高水线复位(回到最开始).

4.速度,一般来说: drop>; truncate >; delete

5.安全性:小心使用drop 和truncate,尤其没有备份的时候.否则哭都来不及使用上,想删除部分数据行用delete,注意带上where子句. 回滚段要足够大.想删除表,当然用drop
    想保留表而将所有数据删除. 如果和事务无关,用truncate即可. 如果和事务有关,或者想触发trigger,还是用delete. 如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据

DELETE   语句每次删除一行,并在事务日志中为所删除的每行记录一项。

TRUNCATE   TABLE   通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。 

TRUNCATE   TABLE   删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用   DELETE。如果要删除表定义及其数据,请使用   DROP   TABLE   语句。

对于由   FOREIGN   KEY   约束引用的表,不能使用   TRUNCATE   TABLE,而应使用不带   WHERE   子句的   DELETE   语句。由于   TRUNCATE   TABLE   不记录在日志中,所以它不能激活触发器。

TRUNCATE   TABLE   不能用于参与了索引视图的表。

 

 

PS:附加说明两个知识点:回滚 与 高水位

1、  回滚

1.在Oracle 中数据删除后还能回滚是因为它把原始数据放到了undo表空间,

2.DML语句使用undo表空间,DDL语句不使用undo,而delete是DML语句,truncate是DDL语句,别外DDL语句是隐式提交.所以truncate操用不能回滚,而delete操作可以.

2、  高水位

所有的Oracle表都有一个容纳数据的上限(很象一个水库历史最高的水位),我们把这个上限称为“high water mark”或HWM。这个HWM是一个标记(专门有一个数据块用来记录高水标记等),用来说明已经有多少数据块分配给这个表. HWM通常增长的幅度为一次5个数据块.

delete语句不影响表所占用的数据块, 高水线(high watermark)保持原位置不动

truncate 语句缺省情况下空间释放,除非使用reuse storage;   truncate会将高水线复位

下面对两种操作对比

SQL> analyze table t estimate statistics;

Table analyzed.

SQL> select segment_name,blocks from dba_segments where segment_name=upper('t');

SEGMENT_NAME                       BLOCKS

------------------------------ ----------

T                                      24

SQL> select table_name,blocks,empty_blocks from user_tables where table_name=upper('t');

TABLE_NAME                         BLOCKS EMPTY_BLOCKS

------------------------------ ---------- ------------

T                                      20            3

USER_TABLES.BLOCKS 列代表该表中曾经使用过得数据库块的数目,即水线。

注意:USER_TABLES.BLOCKS EMPTY_BLOCKS (20+3=23)比DBA_SEGMENTS.BLOCKS少一个数据库块,,这是因为有一个数据库块被保留用作表头。DBA_SEGMENTS.BLOCKS 表示分配给这个表的所有的数据库块的数目。USER_TABLES.BLOCKS表示已经使用过的数据库块的数目(水线)。

linux

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn