您好,登錄后才能下訂單哦!
數(shù)據(jù)庫的運(yùn)維中,經(jīng)常會(huì)遇到delete drop truncate的操作,那么如何去把握它們的用法和區(qū)別呢?
比如當(dāng)數(shù)據(jù)庫空間爆滿,已經(jīng)增長(zhǎng)到存儲(chǔ)空間單個(gè)存儲(chǔ)文件的最大值32G。你需要通過一些辦法釋放掉表空間或者擴(kuò)容表空間來解決問題。
一般當(dāng)系統(tǒng)中大量使用分區(qū)表,而針對(duì)分區(qū)表清除數(shù)據(jù),是不會(huì)釋放表空間的,必須把分區(qū)drop掉,才會(huì)釋放空間。
下面我們具體了解一下這三個(gè)命令:
一、delete
1、delete是DML,執(zhí)行delete操作時(shí),每次從表中刪除一行,并且同時(shí)將該行的的刪除操作記錄在redo和undo表空間中以便進(jìn)行回滾(rollback)和重做操作,但要注意表空間要足夠大,需要手動(dòng)提交(commit)操作才能生效,可以通過rollback撤消操作。
2、delete可根據(jù)條件刪除表中滿足條件的數(shù)據(jù),如果不指定where子句,那么刪除表中所有記錄。
3、delete語句不影響表所占用的extent,高水線(high watermark)保持原位置不變。
注:delete的可閃回恢復(fù)。
二、truncate
1、truncate是DDL,會(huì)隱式提交,所以不能回滾,不會(huì)觸發(fā)觸發(fā)器。truncate操作同沒有where條件的delete操作十分相似,只是把表里的信息全部刪除,但是表依然存在。
2、truncate會(huì)刪除表中所有記錄,并且將重新設(shè)置高水線和所有的索引,缺省情況下將空間釋放到minextents個(gè)extent,除非使用reuse storage。不會(huì)記錄日志,所以執(zhí)行速度很快,但不能通過rollback撤消操作(如果一不小心把一個(gè)表truncate掉,也是可以恢復(fù)的,只是不能通過rollback來恢復(fù))。
3、對(duì)于外鍵(foreignkey )約束引用的表,不能使用truncate table,而應(yīng)使用不帶where子句的 delete 語句。
4、truncatetable不能用于參與了索引視圖的表。
例如:truncate table 后,有可能表空間仍沒有釋放,可以使用如下語句:
alter table 表名稱 deallocate UNUSED KEEP 0;
注意如果不加KEEP 0的話,表空間是不會(huì)釋放的。
或者:
TRUNCATE TABLE (schema)table_name DROP(REUSE) STORAGE才能釋放表空間。
例如: truncate table test1 DROP STORAGE;
三、drop
1、drop是DDL,會(huì)隱式提交,所以不能回滾,不會(huì)觸發(fā)觸發(fā)器。
2、drop語句刪除表結(jié)構(gòu)及所有數(shù)據(jù),并將表所占用的空間全部釋放。
3、drop語句將刪除表的結(jié)構(gòu)所依賴的約束,觸發(fā)器,索引,依賴于該表的存儲(chǔ)過程/函數(shù)將保留,但是變?yōu)閕nvalid狀態(tài)。
注:drop后的表被放在回收站(user_recyclebin)里,而不是直接刪除掉。這樣,回收站里的表信息就可以被恢復(fù),或徹底清除。 通過查詢回收站user_recyclebin獲取被刪除的表信息,然后使用語句
flashback table <user_recyclebin.object_name or user_recyclebin.original_name> to before drop [rename to <new_table_name>];
將回收站里的表恢復(fù)為原名稱或指定新名稱,表中數(shù)據(jù)不會(huì)丟失。
若要徹底刪除表,則使用語句:drop table <table_name> purge;
Oracle命令delete truncate drop 的區(qū)別
1. delete/truncate 只刪除數(shù)據(jù)不刪除表,索引的結(jié)構(gòu)。 drop 將刪除表的結(jié)構(gòu)及依賴的 index/constrain/trigger,依賴于該表的procedure/function 將保留,但是變?yōu)?invalid 狀態(tài);
2. delete 是 dml,寫rollback segement,可回滾,速度慢,事務(wù)提交之后才生效??墒褂?flashback閃回恢復(fù)。一次性大批量數(shù)據(jù)的 delete 可能導(dǎo)致回滾段急劇擴(kuò)展從而影響到數(shù)據(jù)庫,慎用觸發(fā) trigger。 truncate/drop 是 ddl,隱式提交,不寫 rollback segment,不能回滾,速度快。
3. delete 不影響表所占用的 extent,HWM 保持原位置不動(dòng),即使刪除的是最靠近 HWM 的數(shù)據(jù)。delete 其實(shí)也可以釋放空間,但是不降低 HWM,delete 后 block 的空閑空間達(dá)到 pct_used,就可以重用。 truncate 缺省情況下將空間(表和索引)釋放到 minextents 個(gè) extent,除非使用 reuse storage。truncate 會(huì)將高水線復(fù)位(回到最開始)。 drop 將表所占用的空間全部釋放,segment 不存在,無所謂 HWM 的概念;
Oracle高水位(HWM) 解釋
http://blog.csdn.net/tianlesoftware/archive/2009/10/22/4707900.aspx
4. truncate/drop 的對(duì)象必須是本模式下的,或者被授予 drop any table 的權(quán)限,但 drop any table 權(quán)限不能 truncate/drop sys 的表。 delete 的對(duì)象必須是本模式下的,或者被授予 delete on SCHEMA.table 或 delete any table 的權(quán)限,但 delete any table 權(quán)限不能 delete sys 的表;
5. 不能 truncate 一個(gè)帶有 enable 外鍵的表,不管表里有沒有數(shù)據(jù),如果要 truncate,首先要 disable 外鍵或者刪除外鍵(drop 外鍵的表肯定是刪除了外鍵)。不能 drop 一個(gè)帶有 enable 外鍵的表,不管表里有沒有數(shù)據(jù),如果要 drop,首先要?jiǎng)h除外鍵,或者直接用 drop table TABLE_NAMEcascade constraints; 級(jí)聯(lián)刪除外鍵。 delete 可以。
總結(jié):
1、在速度上,一般來說,drop> truncate > delete。
2、在使用drop和truncate時(shí)一定要注意,雖然可以恢復(fù),但為了減少麻煩,還是要慎重。
3、如果想刪除部分?jǐn)?shù)據(jù)用delete,注意帶上where子句,回滾段要足夠大;如果想刪除表,當(dāng)然用drop;如果想保留表而將所有數(shù)據(jù)刪除,如果和事務(wù)無關(guān),用truncate即可;如果和事務(wù)有關(guān),或者想觸發(fā)trigger,還是用delete;如果是整理表內(nèi)部的碎片,可以用truncate跟上reuse stroage,再重新導(dǎo)入/插入數(shù)據(jù)。
補(bǔ)充要注意的:
1、alter table 表名 move 是通過消除行遷移,清除空間碎片,刪除空閑空間,實(shí)現(xiàn)縮小所占的空間,但會(huì)導(dǎo)致此表上的索引無效(因?yàn)镽OWID變了,無法找到),所以執(zhí)行 move 就需要重建索引。還要注意alter table move過程中會(huì)產(chǎn)生鎖,應(yīng)該避免在業(yè)務(wù)高峰期操作!
2、補(bǔ)充一些PURGE知識(shí)
Purge操作:6). Purge index recycle_bin_object_name: 當(dāng)想釋放Recycle bin的空間,又想能恢復(fù)表時(shí),可以通過釋放該對(duì)象的index所占用的空間來緩解空間壓力。 因?yàn)樗饕强梢灾亟ǖ摹?/p>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。