在某些情況下業務建的表某些列沒有用到,需要進行刪除,但是如果是資料量很大的大表,直接 alter table table_name drop column column_name;這種方法刪除,那麼將出現TM表鎖,業務有可能hang住,所以不能這樣子操作;Oracle 8i 引入了從表中刪除列的能力。在此之前,有必要刪除整個表並重建它。可以將列標記為未使用(邏輯刪除)或完全刪除(物理刪除),下面介紹邏輯刪除和物理刪除。
一.邏輯刪除
在大表上,物理刪除列的過程非常耗時且耗費資源。決定從邏輯上刪除最合適。實際上並未刪除目標列資料或恢復這些列佔用的磁碟空間。但是,標記為未使用的列不會顯示在查詢或資料字典檢視中,並且會刪除其名稱,以便新列可以重用該名稱。列上定義的所有約束、索引和統計資訊也將被刪除。
語法:
alter table table_name set unused (column_name);
alter table table_name set unused (column_name1, column_name2);
注意:set unused 語句是不可逆的操作,意思就是不能進行recover,除非你有備份。
完成此操作後,將不再看到這些列。如果以後您有時間物理刪除列,可以使用以下方法完成。
alter table table_name drop unused columns;語句是對未使用的列唯一允許的操作。它從表中物理刪除未使用的列並回收磁碟空間。
alter table table_name drop unused columns checkpoint XX;該子句導致在處理指定數量的行後應用檢查點,在本例中為 1000。檢查點減少了刪除列操作期間累積的undo日誌量,以避免undo空間的潛在耗盡。
DBA_UNUSED_COL_TABS 檢視可用於檢視每個表未使用的列數。
例如我需要刪除user_order_detail 的DEL_IND,DEL_USER_ID,DEL_DTT這三列。
select count(*) from user_order_detail ;
alter table user_order_detail set unused (DEL_IND,DEL_USER_ID,DEL_DTT); --這個執行是秒級別的非常快
select * from DBA_UNUSED_COL_TABS;
alter table user_order_detail drop unused columns checkpoint 1000; --這個執行看你的資料量,物理刪除比較慢。從表中物理刪除未使用的列並回收磁碟空間。
可以想象,才200多萬資料刪除3列這麼久,如果不是採用set unused 這種方法刪除,直接物理刪除千萬甚至億級別的資料,業務響應將是多麼的可怕。
二.物理刪除
要物理刪除列,您可以使用以下語法之一,具體取決於您希望刪除單個列還是多個列。
alter table table_name drop column column_name;
alter table table_name drop (column_name1, column_name2);
同時,從表中刪除一列將導致該表中所有未使用的列同時被刪除(即有set unused 的列將被刪除)。
大表一般不用這種方法刪除,對業務影響太嚴重,小表就可以這麼操作,在及時性要求不高的情況下。
最後
如果刪除列之後,即:
alter table table_name set unused (column_name);有進行alter table table_name move;操作,至於move 和shrink操作的影響以及區別我在索引帖子裡面已經說到過。