truncate是oracle中獨有的關鍵字吧!它的作用是清空一個表格,在刪除數據方面,其與delete有一些區別,以便自己記住:

1、在功能上,truncate是清空一個表的內容,它相當於delete from table_name。
2、delete是dml操作,truncate是ddl操作;因此,用delete刪除整個表的數據時,會產生大量的roolback,佔用很多的rollback segments, 而truncate不會。
3、在內存中,用delete刪除數據,表空間中其被刪除數據的表佔用的空間還在,便於以後的使用,另外它是“假相”的刪除,相當於windows中用delete刪除數據是把數據放到回收站中,還可以恢復,當然如果這個時候重新啓動系統(OS或者RDBMS),它也就不能恢復了!
而用truncate清除數據,內存中表空間中其被刪除數據的表佔用的空間會被立即釋放,相當於windows中用shift+delete刪除數據,不能夠恢復!
4、truncate 調整high water mark 而delete不;truncate之後,TABLE的HWM退回到 INITIAL和NEXT的位置(默認)delete 則不可以。
5、truncate 只能對TABLE,delete 可以是table,view,synonym。
6、TRUNCATE TABLE 的對象必須是本模式下的,或者有drop any table的權限 而 DELETE 則是對象必須是本模式下的,或被授予 DELETE ON SCHEMA.TABLE 或DELETE ANY TABLE的權限。
7、truncate和delete只刪除數據,而drop則刪除整個表(結構和數據)。
8、TRUNCATE將重新設置高水平綫和所有的索引。在對整個表和索引進行完全瀏覽時,經過TRUNCATE操作後的表比Delete操作後的表要快得多。
9、TRUNCATE不能觸發任何Delete觸發器。
10、不能授予任何人清空他人的表的權限。
11、當表被清空後表和表的索引講重新設置成初始大小,而delete則不能。
12、不能清空父表。

刪除表中的數據的方法有delete,truncate,
它們都是刪除表中的數據,而不能刪除表結構,delete 可以刪除整個表的數據也可以刪除表中某一條或N條滿足條件的數據,而truncate只能刪除整個表的數據,一般我們把delete 操作收作刪除表,而truncate操作叫作截斷表.
truncate操作與delete操作對比
操作 回滾 高水綫 空間 效率
Truncate 不能 下降 回收 快
delete 可以 不變 不回收 慢

下面分別用實例查看它們的不同
1.回滾
首先要明白兩點
1.在oracle 中數據刪除後還能回滾是因爲它把原始數據放到了undo表空間,
2.DML語句使用undo表空間,DDL語句不使用undo,而delete是DML語句,truncate是DDL語句,別外DDL語句是隱式提交.
所以truncate操用不能回滾,而delete操作可以.
兩種操作對比(首先新建一個表,並插入數據)
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
Delete刪除,然後回滾
SQL> delete from t;
1 row deleted.
SQL> select * from t;
no rows selected
#刪除後回滾
SQL> rollback;
Rollback complete.
SQL> select * from t;
I
----------
10
Truncate截斷表,然後回滾.
SQL> truncate table t;
Table truncated.
SQL> rollback;
Rollback complete.
SQL> select * from t;
no rows selected
可見delete刪除表還可以回滾,而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表示已經使用過的數據庫塊的數目(水綫)。
Delete刪除表,
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
Truncate截斷表
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
可見,delete表,BLOCK(高水綫)不變,而truncate表BLOCKS(高水綫)變爲0
現在我們也看到blocks+empty_blocks=7,也就是oracle分配區時默認一次7+1(表頭)=8個blocks;
高水綫的作用: HWM對數據庫的操作有如下影響:
a) 全表掃描通常要讀出直到HWM標記的所有的屬於該表數據庫塊,即使該表中沒有任何數據。
b) 即使HWM以下有空閒的數據庫塊,鍵入在插入數據時使用了append關鍵字,則在插入時使用HWM以上的數據塊,此時HWM會自動增大。
因此高水綫是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
Delete刪除表
SQL> delete from t;
100000 rows deleted.
Elapsed: 00:00:20.09
Truncate 截斷表
#先把表回滾
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
可見刪除同一個大小的表,delete用了20.09秒,而truncate只用了0.2秒.