zoukankan      html  css  js  c++  java
  • 【转载】alter table move 和 alter table shrink space的区别

    move 和shrink 的共同点
    1、收缩段
    2、消除部分行迁移
    3、消除空间碎片
    4、使数据更紧密

    shrink



    语法:
      alter table TABLE_NAME shrink space [compact|cascate]

    segment shrink执行的两个阶段:
    1、数据重组(compact):

    通过一系列insert、delete操作,将数据尽量排列在段的前面。在这个过程中需要在表上加RX锁,即只在需要移动的行上加锁。
    由于涉及到rowid的改变,需要enable row movement.同时要disable基于rowid的trigger.这一过程对业务影响比较小。

    2、HWM调整:第二阶段是调整HWM位置,释放空闲数据块。

    此过程需要在表上加X锁,会造成表上的所有DML语句阻塞。在业务特别繁忙的系统上可能造成比较大的影响。
    注意:shrink space语句两个阶段都执行。
    shrink space compact只执行第一个阶段。
    如果系统业务比较繁忙,
    可以先执行shrink space compact重组数据,然后在业务不忙的时候再执行shrink space降低HWM释放空闲数据块。



    举例

      alter table TABLE_NAME shrink space compact;  只整理碎片 不回收空间,  
      alter table TABLE_NAME shrink space;                 整理碎片并回收空间。

      alter table TABLE_NAME shrink space cascade;    整理碎片回收空间 并连同表的级联对象一起整理(比如索引)
      --分区表
      alter table ticket modify  PARTITION P28071 shrink space cascade


    shrink的优点
    1.可在线执行
    2.可使用参数cascade,同时收缩表上的索引
    3.执行后不会导致索引失效
    4.可避免alter table move执行过程中占用很多表空间(如果表10G大小,那alter table move差不多还得需要10G空间才能执行)。

    shrink 使用条件:
    使用步骤
      1. alter table t1 enable  ROW MOVEMENT;
      2. shrink 操作
      3. alter table t1 disable  ROW MOVEMENT;

    shrink使用限制:
    Shrink 操作需满足表空间是本地管理和自动段空间管理(10g、11g默认就是这样),
    以下情况不能用shrink:

    IOT索引组织表
    用rowid创建的物化视图的基表
    带有函数索引的表
    SECUREFILE 类型的大对象
    压缩表



    move



    move解决的问题
    1、将一个table从当前的tablespace上移动到另一个tablespace上:

    alter table t move tablespace tablespace_name;
    alter table TABLE_NAME move ;                                                    --在原来的表空间内部移动。

    2、来改变table已有的block的存储参数,如:

        alter table t move storage (initial 30k next 50k);

    3、另外,move操作也可以用来解决table中的行迁移的问题。

    使用move的一些注意事项:
    1、table上的index需要rebuild:
        在前面我们讨论过,move操作后,数据的rowid发生了改变,我们知道,index是通过rowid来fetch数据行的,所以,table上的index是必须要rebuild的。
        alter index index_name rebuild online;
    2、move时对table的锁定
        当我们对table进行move操作时,查询v$locked_objects视图可以发现,table上加了exclusive lock
    3、关于move时空间使用的问题:
        当我们使用alter table move来降低table的HWM时,有一点是需要注意的,这时,当前的tablespace中需要有1倍于table的空闲空间以供使用。


    move和hrink的区别是:
    1、move后,表在表空间中的位置肯定会变,可能前移也可能后移,一般来说如果该表前面的表空间中有足够空间容纳该表,则前移,否则后移。
    2、hrink后,表在表空间中的位置肯定不变,也就是表的段头位置不会发生变化。

    3、Move会移动高水位,但不会释放申请的空间,是在高水位以下(below HWM)的操作。
    4、shrink space 同样会移动高水位,但也会释放申请的空间,是在高水位上下(below and above HWM)都有的操作。

    5、使用move时,会改变一些记录的ROWID,所以MOVE之后索引会变为无效,需要REBUILD。
    6、使用shrink space时,索引会自动维护。如果在业务繁忙时做压缩,
        可以先shrink space compact,来压缩数据而不移动HWM,等到不繁忙的时候再shrink space来移动HWM。


    7、shrink可以单独压缩索引,alter index xxx shrink space来压缩索引。另外、压缩表时指定Shrink space cascade会同时压缩索引,




    测试

    SQL> 
    SQL> drop table  test  purge;
    SQL> drop table  test2        purge;
    SQL> 
    SQL> create table test (id number) storage (initial 10m next 1m) tablespace users;
    SQL> create table test2 (id number) storage (initial 10m next 1m) tablespace users;
    SQL> 
    SQL> insert into test values(1);
    SQL> insert into test2 values(1);
    SQL> 
    SQL> analyze table test compute statistics;
    SQL> analyze table test2 compute statistics;
    SQL> 
    SQL> col SEGMENT_NAME for a10;
    SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME in ('TEST','TEST2');
    SEGMENT_NA                                EXTENTS                                 BLOCKS                                   INIT
    ---------- -------------------------------------- -------------------------------------- --------------------------------------
    TEST2                                           3                                   1280                                     10
    TEST                                            3                                   1280                                     10
    --两个表,原始申请的分区数和数据块数
    SQL> col TABLE_NAME for a10;
    SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name in ('TEST','TEST2');
    TABLE_NAME                                 BLOCKS                           EMPTY_BLOCKS
    ---------- -------------------------------------- --------------------------------------
    TEST                                           46                                   1234
    TEST2                                          46                                   1234
    --两个表,实际使用的数据块数46,空闲数据块数1234。
    SQL> 
    SQL> begin
      2   for i in 1..100000 loop
      3  insert into test values(i);
      4  insert into test2 values(i);
      5  end loop;
      6  end;
      7  /
    SQL> 
    SQL> analyze table test compute statistics;
    SQL> analyze table test2 compute statistics;
    SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME in ('TEST','TEST2');
    SEGMENT_NA                                EXTENTS                                 BLOCKS                                   INIT
    ---------- -------------------------------------- -------------------------------------- --------------------------------------
    TEST2                                           3                                   1280                                     10
    TEST                                            3                                   1280                                     10
    --插入大量数据后,两个表的原始申请分区数和数据块数,没有变化
    SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name in ('TEST','TEST2');
    TABLE_NAME                                 BLOCKS                           EMPTY_BLOCKS
    ---------- -------------------------------------- --------------------------------------
    TEST                                          174                                   1106
    TEST2                                         174                                   1106
    --插入大量数据后,两个表实际使用的数据块数发生了变化,使用174块,空闲1106块。174就是高水位线
    SQL> 
    SQL> 
    SQL> delete from test where rownum<=50000;
    SQL> delete from test2 where rownum<=50000;
    SQL> 
    SQL> analyze table test compute statistics;
    SQL> analyze table test2 compute statistics;
    SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME in ('TEST','TEST2');
    SEGMENT_NA                                EXTENTS                                 BLOCKS                                   INIT
    ---------- -------------------------------------- -------------------------------------- --------------------------------------
    TEST2                                           3                                   1280                                     10
    TEST                                            3                                   1280                                     10
    --删除大量数据后,两个表的原始申请分区数和数据块数,没有变化


    SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name in ('TEST','TEST2');
    TABLE_NAME                                 BLOCKS                           EMPTY_BLOCKS
    ---------- -------------------------------------- --------------------------------------
    TEST                                          174                                   1106
    TEST2                                         174                                   1106
    --删除大量数据后,两个表实际使用的数据块数也没有发生变化。即delete不会释放空间


    SQL> 
    SQL> 
    SQL> alter table test move;
    SQL> 
    SQL> analyze table test compute statistics;
    SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME in ('TEST','TEST2');
    SEGMENT_NA                                EXTENTS                                 BLOCKS                                   INIT
    ---------- -------------------------------------- -------------------------------------- --------------------------------------
    TEST2                                           3                                   1280                                     10
    TEST                                            3                                   1280                                     10
    --对test表,做move操作,原始申请分区和数据块数,没有变化。


    SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name in ('TEST','TEST2');
    TABLE_NAME                                 BLOCKS                           EMPTY_BLOCKS
    ---------- -------------------------------------- --------------------------------------
    TEST                                           95                                   1185
    TEST2                                         174                                   1106
    --对test表,做move操作,实际使用数据块数发生变化。
    Move会移动高水位,但不会释放申请的空间,是在高水位以下(below HWM)的操作。


    SQL> 
    SQL> 
    SQL> alter table test2 enable row movement;
    SQL> alter table test2 shrink space;
    SQL> analyze table test2 compute statistics;
    SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME in ('TEST','TEST2');
    SEGMENT_NA                                EXTENTS                                 BLOCKS                                   INIT
    ---------- -------------------------------------- -------------------------------------- --------------------------------------
    TEST2                                           1                                    104                                     10
    TEST                                            3                                   1280                                     10
    --对test2表,做shrink操作,原始申请分区和数据块数,发生了变化
    SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name in ('TEST','TEST2');
    TABLE_NAME                                 BLOCKS                           EMPTY_BLOCKS
    ---------- -------------------------------------- --------------------------------------
    TEST                                           95                                   1185
    TEST2                                          79                                     25
    --对test2表,做shrink操作,实际使用数据块数,发生了变化
    shrink space 同样会移动高水位,但也会释放申请的空间,是在高水位上下(below and above HWM)都有的操作。


    SQL> spool off;

    原文出处:http://www.itpub.net/thread-1866952-1-1.html

  • 相关阅读:
    Java 泛型
    Github
    软件工程----前端
    前端全局缓存的三种方式
    关于IDE的选择
    模拟placeholder
    小程序request封装
    小程序实现大转盘抽奖----踩坑之路
    关于this的理解
    小程序背景图片bug
  • 原文地址:https://www.cnblogs.com/hankyoon/p/5174578.html
Copyright © 2011-2022 走看看