oracle中delete drop truncate的用法和區別

數據庫的運維中,經常會遇到delete drop truncate的操作,那麼如何去把握它們的用法和區別呢?

   比如當數據庫空間爆滿,已經增長到存儲空間單個存儲文件的最大值32G。你需要通過一些辦法釋放掉表空間或者擴容表空間來解決問題。

    一般當系統中大量使用分區表,而針對分區表清除數據,是不會釋放表空間的,必須把分區drop掉,纔會釋放空間。

   下面我們具體瞭解一下這三個命令:

 一、delete

1、delete是DML,執行delete操作時,每次從表中刪除一行,並且同時將該行的的刪除操作記錄在redo和undo表空間中以便進行回滾(rollback)和重做操作,但要注意表空間要足夠大,需要手動提交(commit)操作才能生效,可以通過rollback撤消操作。

2、delete可根據條件刪除表中滿足條件的數據,如果不指定where子句,那麼刪除表中所有記錄。

3、delete語句不影響表所佔用的extent,高水線(high watermark)保持原位置不變。

注:delete的可閃回恢復。


二、truncate

1、truncate是DDL,會隱式提交,所以不能回滾,不會觸發觸發器。truncate操作同沒有where條件的delete操作十分相似,只是把表裏的信息全部刪除,但是表依然存在。

2、truncate會刪除表中所有記錄,並且將重新設置高水線和所有的索引,缺省情況下將空間釋放到minextents個extent,除非使用reuse storage。不會記錄日誌,所以執行速度很快,但不能通過rollback撤消操作(如果一不小心把一個表truncate掉,也是可以恢復的,只是不能通過rollback來恢復)。

3、對於外鍵(foreignkey )約束引用的表,不能使用truncate table,而應使用不帶where子句的 delete 語句。

4、truncatetable不能用於參與了索引視圖的表。


例如:truncate table 後,有可能表空間仍沒有釋放,可以使用如下語句:

alter table 表名稱 deallocate   UNUSED KEEP 0;

注意如果不加KEEP 0的話,表空間是不會釋放的。

或者:

TRUNCATE TABLE (schema)table_name DROP(REUSE) STORAGE才能釋放表空間。

例如: truncate table  test1 DROP STORAGE;


三、drop

1、drop是DDL,會隱式提交,所以不能回滾,不會觸發觸發器。

2、drop語句刪除表結構及所有數據,並將表所佔用的空間全部釋放。

3、drop語句將刪除表的結構所依賴的約束,觸發器,索引,依賴於該表的存儲過程/函數將保留,但是變爲invalid狀態。

注:drop後的表被放在回收站(user_recyclebin)裏,而不是直接刪除掉。這樣,回收站裏的表信息就可以被恢復,或徹底清除。 通過查詢回收站user_recyclebin獲取被刪除的表信息,然後使用語句

                   flashback table <user_recyclebin.object_name or user_recyclebin.original_name> to before drop [rename to <new_table_name>];

                   將回收站裏的表恢復爲原名稱或指定新名稱,表中數據不會丟失。

                   若要徹底刪除表,則使用語句:drop table <table_name> purge;                   


Oracle命令delete truncate drop 的區別

1. delete/truncate 只刪除數據不刪除表,索引的結構。 drop 將刪除表的結構及依賴的 index/constrain/trigger,依賴於該表的procedure/function 將保留,但是變爲 invalid 狀態;

 

2. delete 是 dml,寫rollback segement,可回滾,速度慢,事務提交之後才生效。可使用 flashback閃回恢復。一次性大批量數據的 delete 可能導致回滾段急劇擴展從而影響到數據庫,慎用觸發 trigger。 truncate/drop 是 ddl,隱式提交,不寫 rollback segment,不能回滾,速度快。

 

3. delete 不影響表所佔用的 extent,HWM 保持原位置不動,即使刪除的是最靠近 HWM 的數據。delete 其實也可以釋放空間,但是不降低 HWM,delete 後 block 的空閒空間達到 pct_used,就可以重用。 truncate 缺省情況下將空間(表和索引)釋放到 minextents 個 extent,除非使用 reuse storage。truncate 會將高水線復位(回到最開始)。 drop 將表所佔用的空間全部釋放,segment 不存在,無所謂 HWM 的概念;

 

Oracle高水位(HWM) 解釋

http://blog.csdn.net/tianlesoftware/archive/2009/10/22/4707900.aspx        

  

 

4. truncate/drop 的對象必須是本模式下的,或者被授予 drop any table 的權限,但 drop any table 權限不能 truncate/drop sys 的表。 delete 的對象必須是本模式下的,或者被授予 delete on SCHEMA.table 或 delete any table 的權限,但 delete any table 權限不能 delete sys 的表;

 

5. 不能 truncate 一個帶有 enable 外鍵的表,不管表裏有沒有數據,如果要 truncate,首先要 disable 外鍵或者刪除外鍵(drop 外鍵的表肯定是刪除了外鍵)。不能 drop 一個帶有 enable 外鍵的表,不管表裏有沒有數據,如果要 drop,首先要刪除外鍵,或者直接用 drop table TABLE_NAMEcascade constraints; 級聯刪除外鍵。 delete 可以。

 

總結:

1、在速度上,一般來說,drop> truncate > delete。

2、在使用drop和truncate時一定要注意,雖然可以恢復,但爲了減少麻煩,還是要慎重。

3、如果想刪除部分數據用delete,注意帶上where子句,回滾段要足夠大;如果想刪除表,當然用drop;如果想保留表而將所有數據刪除,如果和事務無關,用truncate即可;如果和事務有關,或者想觸發trigger,還是用delete;如果是整理表內部的碎片,可以用truncate跟上reuse stroage,再重新導入/插入數據。


補充要注意的:

1、alter table 表名 move 是通過消除行遷移,清除空間碎片,刪除空閒空間,實現縮小所佔的空間,但會導致此表上的索引無效(因爲ROWID變了,無法找到),所以執行 move 就需要重建索引。
找到表對應的索引。
select index_name,table_name,tablespace_name,index_type,status  from dba_indexes  where table_owner='SCOTT' ;
根據status 的值,重建無效的就行了。
sql='alter index '||index_name||' rebuild'; 使用存儲過程執行,稍微安慰。

還要注意alter table move過程中會產生鎖,應該避免在業務高峯期操作!


2、補充一些PURGE知識

Purge操作:
1). Purge tablespace tablespace_name : 用於清空表空間的Recycle Bin
2). Purge tablespace tablespace_name user user_name: 清空指定表空間的Recycle Bin中指定用戶的對象
3). Purge recyclebin: 刪除當前用戶的Recycle Bin中的對象
4). Purge dba_recyclebin: 刪除所有用戶的Recycle Bin中的對象,該命令要sysdba權限
5). Drop table table_name purge:  刪除對象並且不放在Recycle Bin中,即永久的刪除,不能用Flashback恢復。

6). Purge index recycle_bin_object_name: 當想釋放Recycle bin的空間,又想能恢復表時,可以通過釋放該對象的index所佔用的空間來緩解空間壓力。 因爲索引是可以重建的。



文章來源https://blog.51cto.com/xjsunjie/1847337

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章