实例对比Oracle中truncate和delete的区别
2013-10-18 10:53
543 查看
实例对比Oracle中truncate和delete的区别
删除表中的数据的方法有delete,truncate,它们都是删除表中的数据,而不能删除表结构,delete 可以删除整个表的数据也可以删除表中某一条或N条满足条件的数据,而truncate只能删除整个表的数据,一般我们把delete 操作收作删除表,而truncate操作叫作截断表.
[align=center]truncate操作与delete操作对比[/align]
[align=center]操作[/align] | [align=center]回滚[/align] | [align=center]高水线[/align] | [align=center]空间[/align] | [align=center]效率[/align] |
[align=center]Truncate[/align] | [align=center]不能[/align] | [align=center]下降[/align] | [align=center]回收[/align] | [align=center]快[/align] |
[align=center]delete[/align] | [align=center]可以[/align] | [align=center]不变[/align] | [align=center]不回收[/align] | [align=center]慢[/align] |
1.回滚
首先要明白两点1.在oracle 中数据删除后还能回滚是因为它把原始数据放到了undo表空间,
2.DML语句使用undo表空间,DDL语句不使用undo,而delete是DML语句,truncate是DDL语句,别外DDL语句是隐式提交.
所以truncate操用不能回滚,而delete操作可以.(正是因为DDL语句是隐式提交,所以它不需要使用undo表空间)
两种操作对比(首先新建一个表,并插入数据)
SQL> create table t 2 ( 3 i number 4 ); Table created. SQL> insert into t values(10); SQL> commit; Commit complete. SQL> select * from t; I ---------- 10 |
SQL> delete from t; 1 row deleted. SQL> select * from t; no rows selected #删除后回滚 SQL> rollback; Rollback complete. SQL> select * from t; I ---------- 10 |
SQL> truncate table t; Table truncated. SQL> rollback; Rollback complete. SQL> select * from t; no rows selected |
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 |
注意:
1、USER_TABLES.BLOCKS和USER_TABLES.EMPTY_BLOCKS (20+3=23)比DBA_SEGMENTS.BLOCKS少一个数据库块,这是因为有一个数据库块被保留用作表头。DBA_SEGMENTS.BLOCKS表示分配给这个表的所有的数据库块的数目。USER_TABLES.BLOCKS表示已经使用过的数据库块的数目(水线)。
2、
DBA_SEGMENTS.BLOCKS 表示分配给这个表(所在段)的所有的数据库块的数目。
USER_TABLES.BLOCKS 表示已经使用过的数据库块的数目(水线)。
USER_TABLES.EMPTY_BLOCKS 表示分配给这个表(所在段)的所有的数据库块的数目中还未被表使用过的数据库块的数目,即DBA_SEGMENTS.BLOCKS -USER_TABLES.BLOCKSDelete删除表,
SQL> delete from t; 10000 rows deleted SQL> commit; Commit complete. SQL> analyze table t estimate statistics; Table analyzed. SQL> select table_name,blocks,empty_blocks from user_tables where table_name=upper('t'); TABLE_NAME BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------------------------------------------------------------- T 20 3 |
SQL> truncate table t; Table truncated. SQL> analyze table t estimate statistics; Table analyzed. SQL> select table_name,blocks,empty_blocks from user_tables where table_name=upper('t'); TABLE_NAME BLOCKS EMPTY_BLOCKS ------------------------------ ---------- -------------------------------------------------------- T 0 7 |
现在我们也看到blocks+empty_blocks=7,也就是oracle分配区时默认一次7+1(表头)=8个blocks;
高水线的作用
HWM对数据库的操作有如下影响:
a) 全表扫描通常要读出直到HWM标记的所有的属于该表数据库块,即使该表中没有任何数据。
b) 即使HWM以下有空闲的数据库块,键入在插入数据时使用了append关键字,则在插入时使用HWM以上的数据块,此时HWM会自动增大。
注释:“HWM以下有空闲的数据库块”就是表示已经被表使用过了的数据库块只是现在该块在里面没有数据而已,该块还是属于user_tables.blocks的,不是属于user_tables.empty_blocks的。属于user_tables.empty_blocks的块虽然也是块里面没有数据,但是它还是没有被表使用过了的数据库块。
疑问:delete后,HWM以下就有空闲的数据库块了,那么重新插入数据(没有使用了append关键字)时,会使用这些空闲数据块吗?
答案是会使用空闲数据块的
因此高水线是oracle优化时一个重要的参数
3.空间
既然高水线用来说明已经有多少数据块分配给这个表,那么高水线也可理解为表的空间占用。即使delete将表中的数据全部删除,HWM还是为原值,所以还有那么多的空间分配给这个表,即它的空间还没有回收,
而truncate表后高水线变为0,那现在它就表示没有分配空间,即它的空间被回收了。
4.效率
要想查看delete,truncate那个效率更高,先构建一个大表,然后查看它们分别对些表删除所需的时间。有个相当形象的比喻:领导给你两本书让你扔掉,delete就是你守在复印机前,把书一页页撕下来复印一份,再一页页扔到垃圾桶里,truncate就是直接把两本书扔到垃圾桶里,那个快那个慢不言而喻。
先在表中插入100000条记录,并打开时间
SQL> set timing on; SQL> begin 2 for i in 1..100000 loop 3 insert into t values('10'); 4 commit; 5 end loop; 6 end; 7 / PL/SQL procedure successfully completed. Elapsed: 00:01:12.50 |
SQL> delete from t; 100000 rows deleted. Elapsed: 00:00:20.09 |
#先把表回滚 SQL> rollback; Rollback complete. Elapsed: 00:00:17.36 SQL> select count(*) from t; COUNT(*) ------------------- 100000 Elapsed: 00:00:00.01 SQL> truncate table t; Table truncated. Elapsed: 00:00:00.20 |
本文出自 “追求” 博客,请务必保留此出处/article/4389304.html
相关文章推荐
- ORACLE 临时表空间使用率过高的原因及临时解决方案
- oracle使用游标让存储过程返回记录集
- ORACLE soctt 不能创建视图-权限不足
- Listagg() - Oracle11gR2进行字符串汇总的新函数
- 如何成为一名出色的Oracle数据库管理员
- Oracle Rman 命令详解(List report backup configure)
- [oracle]ORA-21561: OID generation failed
- oracle 有关大数据
- oracle常用数据类型
- ORACLE日期时间函数大全
- oracle参数文件的本质
- Oracle 的to_char、to_number…
- Oracle行级锁的本质
- oracle 命令 积累
- oracle的分页查询
- 解析oracle的rownum
- oracle在操作主、外键需要注意的ORA-02449、ORA-02298
- oracle 临时表空间的增删改查
- ORACLE分析函数(6)--使用listagg实现行列转换
- Oracle EBS R12 开放环境