oracle alter table alter table move跟shrink space的区别

alter table move跟shrink space的区别

  今天主要从两点说他们的区别:

  1. 碎片的整理

  2.空间的收缩

  SQL> select * from v$version;

  BANNER

  -------------------------------------------------- --------------

  Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi

  PL/SQL Release 10.2.0.1.0 - Production

  CORE 10.2.0.1.0 Production

  TNS for Linux: Version 10.2.0.1.0 - Production

  NLSRTL Version 10.2.0.1.0 - Production

  SQL>

  创建测试表

  SQL> create table test3 as

  2 select rownum id,

  3 dbms_random.string('a', round(dbms_random.value(0,10))) col1,

  4 trunc(sysdate) - dbms_random.value(1, 365*2) col2

  5 from dual connect by rownum<=10000;

  Table created

  SQL> select count(1) from test3;

  COUNT(1)

  ----------

  10000

  查看表test3的blocks使用情况:

  SQL> exec show_space_t('TEST3','auto','table','Y');

  Total Blocks............................40

  Total Bytes.............................327680

  Unused Blocks...........................3

  Unused Bytes............................24576

  Last Used Ext FileId....................31

  Last Used Ext BlockId...................481921

  Last Used Block.........................5

  *************************************************

  0% -- 25% free space blocks.............0

  0% -- 25% free space bytes..............0

  25% -- 50% free space blocks............0

  25% -- 50% free space bytes.............0

  50% -- 75% free space blocks............0

  50% -- 75% free space bytes.............0

  75% -- 100% free space blocks...........0

  75% -- 100% free space bytes............0

  Unused Blocks...........................0

  Unused Bytes............................0

  Total Blocks............................32

  Total bytes.............................262144

  PL/SQL procedure successfully completed

  制造碎片

  SQL> DELETE FROM TEST3 WHERE MOD(ID,3)=1;

  3334 rows deleted

  SQL> commit;

  Commit complete

  发现有碎片了

  SQL> exec show_space_t('TEST3','auto','table','Y');

  Total Blocks............................40

  Total Bytes.............................327680

  Unused Blocks...........................3

  Unused Bytes............................24576

  Last Used Ext FileId....................31

  Last Used Ext BlockId...................481921

  Last Used Block.........................5

  *************************************************

  0% -- 25% free space blocks.............0

  0% -- 25% free space bytes..............0

  25% -- 50% free space blocks............31

  25% -- 50% free space bytes.............253952

  50% -- 75% free space blocks............1

  50% -- 75% free space bytes.............8192

  75% -- 100% free space blocks...........0

  75% -- 100% free space bytes............0

  Unused Blocks...........................0

  Unused Bytes............................0

  Total Blocks............................0

  Total bytes.............................0

  PL/SQL procedure successfully completed

  SQL>

  消除碎片

  SQL> alter table test3 move;

  Table altered

  查看碎片消除的效果

  SQL> exec show_space_t('TEST3','auto','table','Y');

  Total Blocks............................32

  Total Bytes.............................262144

  Unused Blocks...........................6

  Unused Bytes............................49152

  Last Used Ext FileId....................31

  Last Used Ext BlockId...................485065

  Last Used Block.........................2

  *************************************************

  0% -- 25% free space blocks.............0

  0% -- 25% free space bytes..............0

  25% -- 50% free space blocks............0

  25% -- 50% free space bytes.............0

  50% -- 75% free space blocks............0

  50% -- 75% free space bytes.............0

  75% -- 100% free space blocks...........0

  75% -- 100% free space bytes............0

  Unused Blocks...........................0

  Unused Bytes............................0

  Total Blocks............................22

  Total bytes.............................180224

  PL/SQL procedure successfully completed

  SQL>

  从以上看,碎片整理的效果很好!!!

  下面在测试用shrink整理碎片

  重建测试环境

  SQL> drop table test3;

  Table dropped

  SQL>

  SQL> create table test3 as

  2 select rownum id,

  3 dbms_random.string('a', round(dbms_random.value(0,10))) col1,

  4 trunc(sysdate) - dbms_random.value(1, 365*2) col2

  5 from dual connect by rownum<=10000;

  Table created

  查看test3的blocks的使用

  SQL> exec show_space_t('TEST3','auto','table','Y');

  Total Blocks............................40

  Total Bytes.............................327680

  Unused Blocks...........................3

  Unused Bytes............................24576

  Last Used Ext FileId....................31

  Last Used Ext BlockId...................481921

  Last Used Block.........................5

  *************************************************

  0% -- 25% free space blocks.............0

  0% -- 25% free space bytes..............0

  25% -- 50% free space blocks............0

  25% -- 50% free space bytes.............0

  50% -- 75% free space blocks............0

  50% -- 75% free space bytes.............0

  75% -- 100% free space blocks...........0

  75% -- 100% free space bytes............0

  Unused Blocks...........................0

  Unused Bytes............................0

  Total Blocks............................32

  Total bytes.............................262144

  PL/SQL procedure successfully completed

  制造碎片

  SQL> delete from test3 where mod(id,3)=1;

  3334 rows deleted

  SQL> commit;

  Commit complete

  查看碎片情况

  SQL> exec show_space_t('TEST3','auto','table','Y');

  Total Blocks............................40

  Total Bytes.............................327680

  Unused Blocks...........................3

  Unused Bytes............................24576

  Last Used Ext FileId....................31

  Last Used Ext BlockId...................481921

  Last Used Block.........................5

  *************************************************

  0% -- 25% free space blocks.............0

  0% -- 25% free space bytes..............0

  25% -- 50% free space blocks............31

  25% -- 50% free space bytes.............253952

  50% -- 75% free space blocks............0

  50% -- 75% free space bytes.............0

  75% -- 100% free space blocks...........0

  75% -- 100% free space bytes............0

  Unused Blocks...........................0

  Unused Bytes............................0

  Total Blocks............................1

  Total bytes.............................8192

  PL/SQL procedure successfully completed

  用oracle10g新功能整理碎片

  SQL> alter table test3 shrink space compact cascade;

  alter table test3 shrink space compact cascade

  ORA-10636: ROW MOVEMENT is not enabled

  SQL> alter table test3 enable row movement;

  Table altered SQL> alter table test3 shrink space compact cascade; Table altered 再次查看碎片的情况,发现还有一些碎片,整理碎片效果不好

  SQL> exec show_space_t('TEST3','auto','table','Y');

  Total Blocks............................40

  Total Bytes.............................327680

  Unused Blocks...........................3

  Unused Bytes............................24576

  Last Used Ext FileId....................31

  Last Used Ext BlockId...................481921

  Last Used Block.........................5

  *************************************************

  0% -- 25% free space blocks.............1

  0% -- 25% free space bytes..............8192

  25% -- 50% free space blocks............2

  25% -- 50% free space bytes.............16384

  50% -- 75% free space blocks............0

  50% -- 75% free space bytes.............0

  75% -- 100% free space blocks...........12

  75% -- 100% free space bytes............98304

  Unused Blocks...........................0

  Unused Bytes............................0

  Total Blocks............................17

  Total bytes.............................139264

  PL/SQL procedure successfully completed

  上面是没降低HWM,如果载降低HWM,看看效果

  SQL> alter table test3 shrink space cascade;

  Table altered

  SQL> exec show_space_t('TEST3','auto','table','Y');

  Total Blocks............................24

  Total Bytes.............................196608

  Unused Blocks...........................0

  Unused Bytes............................0

  Last Used Ext FileId....................31

  Last Used Ext BlockId...................481897

  Last Used Block.........................8

  *************************************************

  0% -- 25% free space blocks.............1

  0% -- 25% free space bytes..............8192

  25% -- 50% free space blocks............2

  25% -- 50% free space bytes.............16384

  50% -- 75% free space blocks............0

  50% -- 75% free space bytes.............0

  75% -- 100% free space blocks...........0

  75% -- 100% free space bytes............0

  Unused Blocks...........................0

  Unused Bytes............................0

  Total Blocks............................17

  Total bytes.............................139264

  PL/SQL procedure successfully completed

  看来用shrink space整理碎片不彻底,再来看看move的方式

  SQL> alter table test3 move;

  Table altered

  SQL> exec show_space_t('TEST3','auto','table','Y');

  Total Blocks............................32

  Total Bytes.............................262144

  Unused Blocks...........................6

  Unused Bytes............................49152

  Last Used Ext FileId....................31

  Last Used Ext BlockId...................485081

  Last Used Block.........................2

  *************************************************

  0% -- 25% free space blocks.............0

  0% -- 25% free space bytes..............0

  25% -- 50% free space blocks............0

  25% -- 50% free space bytes.............0

  50% -- 75% free space blocks............0

  50% -- 75% free space bytes.............0

  75% -- 100% free space blocks...........0

  75% -- 100% free space bytes............0

  Unused Blocks...........................0

  Unused Bytes............................0

  Total Blocks............................22

  Total bytes.............................180224

  PL/SQL procedure successfully completed

  效果很明显,整理的很彻底

  测试结论:

  虽然alter table move和shrink space,都是通过物理调整rowid来整理碎片的,但shrink space整理的不彻底,他好像不是重组,而是尽可能的合并,随意会残留一些block无法整理

  注意:

  1.再用alter table table_name move时,表相关的索引会失效,所以之后还要执行 alter index index_name rebuild online; 最后重新编译数据库所有失效的对象

  2. 在用alter table table_name shrink space cascade时,他相当于alter table table_name move和alter index index_name rebuild online. 所以只要编译数据库失效的对象就可以

  alter table move和shrink space除了碎片整理的效果有时不一样外,还有什么其他的不同呢

  1. Move会移动高水位,但不会释放申请的空间,是在高水位以下(below HWM)的操作。

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

  下面通过实验来验证

  SQL> drop table test3;

  Table dropped

  SQL>

  SQL> create table test3 as

  2 select rownum id,

  3 dbms_random.string('a', round(dbms_random.value(0,10))) col1,

  4 trunc(sysdate) - dbms_random.value(1, 365*2) col2

  5 from dual connect by rownum<=10000;

  Table created

  SQL> analyze table test3 compute statistics;

  Table analyzed

  SQL> col segment_name for a10;

  SQL> select us.segment_name,us.extents,us.blocks from user_segments us where us.segment_name=upper('test3');

  SEGMENT_NA EXTENTS BLOCKS

  ---------- ---------- ----------

  TEST3 5 40

  SQL> col table_name for a10;

  SQL> select table_name,blocks,t.empty_blocks from user_tables t where t.table_name=upper('test3');

  TABLE_NAME BLOCKS EMPTY_BLOCKS

  ---------- ---------- ------------

  TEST3 37 3

  SQL>

  从以上查询可以看出共分了5个extents,使用了37个 blocks,这37也就是test3的HWM

  SQL> delete from test3 where rownum<=5000;

  5000 rows deleted

  SQL> commit;

  Commit complete

  SQL> analyze table test3 compute statistics;

  Table analyzed

  SQL> col segment_name for a10;

  SQL> select us.segment_name,us.extents,us.blocks from user_segments us where us.segment_name=upper('test3');

  SEGMENT_NA EXTENTS BLOCKS

  ---------- ---------- ----------

  TEST3 5 40

  SQL> col table_name for a10;

  SQL> select table_name,blocks,t.empty_blocks from user_tables t where t.table_name=upper('test3');

  TABLE_NAME BLOCKS EMPTY_BLOCKS

  ---------- ---------- ------------

  TEST3 37 3

  SQL> select count(distinct dbms_rowid.rowid_block_number(rowid)) used_blocks from test3;

  USED_BLOCKS

  -----------

  17

  我们从查询中可以发现test3的HWM没有变换还是 37blocks,tests总共空间为40blocks。经过删除后test3实际用的块是17个

  下面我们用move降低下HWM

  SQL> alter table test3 move;

  Table altered

  SQL> col segment_name for a10;

  SQL> select us.segment_name,us.extents,us.blocks from user_segments us where us.segment_name=upper('test3');

  SEGMENT_NA EXTENTS BLOCKS

  ---------- ---------- ----------

  TEST3 3 24

  SQL> col table_name for a10;

  SQL> select table_name,blocks,t.empty_blocks from user_tables t where t.table_name=upper('test3');

  TABLE_NAME BLOCKS EMPTY_BLOCKS

  ---------- ---------- ------------

  TEST3 37 3

  user_tables里的数据没有变化,哦,原来 是忘记analyze了,从这里也可以看出user_segments是oracle自动维护的。

  SQL> analyze table test3 compute statistics;

  Table analyzed SQL> select us.segment_name,us.extents,us.blocks from user_segments us where us.segment_name=upper('test3'); SEGMENT_NA EXTENTS BLOCKS

  ---------- ---------- ----------

   TEST3 3 24 SQL> select table_name,blocks,t.empty_blocks from user_tables t where t.table_name=upper('test3'); TABLE_NAME BLOCKS EMPTY_BLOCKS

  ---------- ---------- ------------

  TEST3 20 4 SQL> 现在再来看hwm变为20了,已经降下来了啊,空间也收缩 了,从40blocks降到24blocks(注意收缩到initial指定值)。

  但shrink space就收缩到存储数据的最小值,下面测试说明

  创建测试表:

  SQL> create table test5 (id number) storage (initial 1m next 1m);

  Table created

  初始化数据

  SQL>

  SQL> begin

  2 for i in 1..100000 loop

  3 insert into test5 values(i);

  4 end loop;

  5 end;

  6 /

  PL/SQL procedure successfully completed

  SQL> analyze table test5 compute statistics;

  Table analyzed

  SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/10 24 init from user_segments where SEGMENT_NAME='TEST5';

  SEGMENT_NA EXTENTS BLOCKS INIT

  ---------- ---------- ---------- ----------

  TEST5 17 256 1

  SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST5';

  TABLE_NAME BLOCKS EMPTY_BLOCKS

  ---------- ---------- ------------

  TEST5 180 76

  可以从查询数据看出,test5初始化1m即128个blocks, 但数据比较多,所以又按next参数要求扩展了1m空间,扩展了17个extents。

  这里的test5总空间大小为256个blocks,使用 空间为180blocks,HWM也是180blocks

  SQL> delete from test5 where rownum<=50000;

  50000 rows deleted

  SQL> analyze table test5 compute statistics;

  Table analyzed

  SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/10 24 init from user_segments where SEGMENT_NAME='TEST5';

  SEGMENT_NA EXTENTS BLOCKS INIT

  ---------- ---------- ---------- ----------

  TEST5 17 256 1

  SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST5';

  TABLE_NAME BLOCKS EMPTY_BLOCKS

  ---------- ---------- ------------

  TEST5 180 76

  整理碎片,降低HWM

  SQL> alter table test5 move;

  Table altered

  SQL> analyze table test5 compute statistics;

  Table analyzed

  SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/10 24 init from user_segments where SEGMENT_NAME='TEST5';

  SEGMENT_NA EXTENTS BLOCKS INIT

  ---------- ---------- ---------- ----------

  TEST5 16 128 1

  SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST5';

  TABLE_NAME BLOCKS EMPTY_BLOCKS

  ---------- ---------- ------------

  TEST5 85 43

  从上面的查询数据可以看出HWM已经从180降低到85,test5 总大小从256blocks收缩到128个blocks(initial指定大小)。

  下面看看用shrink space收缩空间的情况

  SQL> alter table test5 enable row movement;

  Table altered

  SQL> alter table test5 shrink space;

  Table altered

  SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/10 24 init from user_segments where SEGMENT_NAME='TEST5';

  SEGMENT_NA EXTENTS BLOCKS INIT

  ---------- ---------- ---------- ----------

  TEST5 11 88 1

  SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST5';

  TABLE_NAME BLOCKS EMPTY_BLOCKS

  ---------- ---------- ------------

  TEST5 85 43

  SQL>

  从上面的数据可以看到test5进一步从128个blocks降低到88个blocks

  结论:

  shrink space收缩到数据存储的最小值,alter table move(不带参数)收缩到initial指定值,也可以用alter table test5 move storage(initial 500k)指定收缩的大小,这样可以达到shrink space效果

  经过以上测试,得出的两个结论,到底用哪一个命令来整理碎片,消除行迁移呢?这就要根据实际业务需要,如果你只是收缩空间,数据增 长很慢,那用shrink可以但是如果数据增长很快的话,用move就比较合适,避免再重新分配空间啊

  备注:

  在10g之后,整理碎片消除行迁移的新 增功能shrink space

  alter table <table_name> shrink space [ <null> | compact | cascade ];

  compact :这个参数当系统的负载比较大时可以 用,不降低HWM。如果系统负载较低时,直接用alter table table_name shrink space就一步到位了

  cascade :这个参数是在shrink table的时候自动级联索引,相当于rebulid index。

  普通表:

  shrink必须开启行迁移功能。

  alter table table_name enable row movement ;

  保持HWM,相当于把块中数据打结实了

  alter table table_name shrink space compact;

  回缩表与降低HWM

  alter table table_name shrink space;

  回缩表与相关索引,降低HWM

  alter table table_name shrink space cascade;

  回缩索引与降低HWM

  alter index index_name shrink space

  虽然在10g中可以用shrink ,但也有些限制:

  1). 对cluster,cluster table,或具有Long,lob类型列的对象 不起作用。

  2). 不支持具有function-based indexes 或 bitmap join indexes的表

  3). 不支持mapping 表或index-organized表。

  4). 不支持compressed 表

  ------end------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值