zoukankan      html  css  js  c++  java
  • 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); --这个执行是秒级别的非常快

    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;


  • 相关阅读:
    由于挂载的nfs存储目录掉下线,导致创建VM时,无法创建
    使用RVM更新Ruby 版本
    安装logstash+kibana+elasticsearch+redis搭建集中式日志分析平台
    Topic modeling【经典模型】
    [第1集] 课程目标,数据类型,运算,变量
    Juint test Case 的2种使用方式
    getJSON方式请求服务器
    Web项目改名的带来的404not found问题
    JavaWeb EL表达式, JSTL标签及过滤器综合学习
    HashMap的几种遍历方式(转载)
  • 原文地址:https://www.cnblogs.com/hmwh/p/15012610.html
Copyright © 2011-2022 走看看