oracle 大表在線刪除列操作(alter table table_name set unused )


在某些情況下業務建的表某些列沒有用到,需要進行刪除,但是如果是數據量很大的大表,直接 alter table table_name drop column column_name;這種方法刪除,那么將出現TM表鎖,業務有可能hang住,所以不能這樣子操作;Oracle 8i 引入了從表中刪除列的能力。在此之前,有必要刪除整個表並重建它。可以將列標記為未使用(邏輯刪除)或完全刪除(物理刪除),下面介紹邏輯刪除和物理刪除。

一.邏輯刪除

在大表上,物理刪除列的過程非常耗時且耗費資源。決定從邏輯上刪除最合適。實際上並未刪除目標列數據或恢復這些列占用的磁盤空間。但是,標記為未使用的列不會顯示在查詢或數據字典視圖中,並且會刪除其名稱,以便新列可以重用該名稱。列上定義的所有約束、索引和統計信息也將被刪除。

語法:

alter table table_name set unused (column_name) ONLINE; --加上ONLINE,業務不阻塞
alter table table_name set unused (column_name1, column_name2);

注意:set unused 語句是不可逆的操作,意思就是不能進行recover,除非你有備份。

完成此操作后,將不再看到這些列。如果以后您有時間物理刪除列,可以使用以下方法完成。

alter table table_name drop unused columns ONLINE ;語句是對未使用的列唯一允許的操作。它從表中物理刪除未使用的列並回收磁盤空間。
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); --這個執行是秒級別的非常快;建議刪除后有觸發器的涉及到這幾列的重建觸發器,oracle19-20c有bug,21c修復次BUG。

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操作的影響以及區別我在索引帖子里面已經說到過。


三.總結一下set unused

1.指定SET UNUSED將一列或多列標記為未使用。對於內部堆組織表,指定此子句實際上不會從表中的每一行中刪除目標列。它不會恢復這些列使用的磁盤空間。因此,響應時間比執行DROP子句時要快

當您為外部表中的列指定此子句時,該子句將透明地轉換為ALTER TABLE...DROP COLUMN語句。這樣做的原因是,對外部表的任何操作都是元數據操作,因此兩個命令的性能沒有區別。

2.用標列的所有表UNUSED中的數據字典視圖USER_UNUSED_COL_TABSDBA_UNUSED_COL_TABSALL_UNUSED_COL_TABS

未使用的列被視為已刪除,即使它們的列數據仍保留在表行中。一列被標記后UNUSED,將無法訪問該列。SELECT 查詢不會檢索未使用的列數據。此外,標記的列的名稱和類型UNUSED在 期間不會顯示DESCRIBE,可以向表中添加一個與未使用的列同名的新列。

3.實際刪除這些列之前,它們將繼續計入單個表中 1000 列的絕對限制。但是,與所有 DDL 語句一樣,不能回滾此子句的結果。不能發出SET USED對應物來檢索您擁有的列SET UNUSED此外,如果您將一LONG列標記為UNUSED,則LONG在您實際刪除未使用的LONG列之前,您無法向表中添加另一列。

4.建議加上ONLINE關鍵字,在線業務很重要,不會阻塞(非阻塞代表dml業務操作沒影響(除了刪除的列),SET UNUSED就會給表加上鎖,ONLINE不影響其他DML);

如果使用ONLINE關鍵字,以下操作現在非阻塞:

  • ALTER TABLE table-name DROP CONSTRAINT contraint-name ONLINE;
  • ALTER TABLE table-name SET UNUSED (column-list) ONLINE;
  • DROP INDEX index-name ONLINE;
  • ALTER INDEX index-name UNUSABLE ONLINE;
  • ALTER TABLE table_name MOVE PARTITION partition-name ONLINE ...;
  • ALTER TABLE table_name MOVE SUBPARTITION partition-name ONLINE ...;

以下操作在沒有ONLINE關鍵字的情況下是非阻塞的

  • ALTER INDEX index-name INVISIBLE;
  • ALTER INDEX index-name VISIBLE;



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM