- 浏览: 52320 次
- 性别:
- 来自: 深圳
-
文章分类
最新评论
-
zixiaolan:
jQuery.event.remove($("#bt ...
CXF restful日志配置 -
zixiaolan:
废话不说,上资源:MySQL数据库视频教程:http://pa ...
CXF restful日志配置 -
zixiaolan:
(关于未来)继往开来,我希望我们群能找到更多的志同道合的途观车 ...
深圳途观车友会2015年年会1 -
zixiaolan:
群还是一个资源共享的平台,什么说是资源共享,有句话说的好,需求 ...
深圳途观车友会2015年年会1 -
zixiaolan:
(关于平台)群发展到今天,每天都有很多人入群,特别是在6-7月 ...
深圳途观车友会2015年年会1
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/1024 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/1024 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/1024 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/1024 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------
今天主要从两点说他们的区别:
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/1024 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/1024 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/1024 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/1024 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------
相关推荐
本文将深入探讨Oracle中的碎片整理,主要关注`ALTER TABLE T MOVE`和`ALTER TABLE T SHRINK SPACE`两个命令。 首先,我们来理解什么是Oracle数据库中的碎片。碎片分为两种类型:内部碎片和外部碎片。内部碎片是指...
最后,给出了几种降低 HWM 的方法,包括 alter table move、shrink space、数据复制、exp/imp 以及 deallocate unused 等方法。 适合人群:具备 Oracle 数据库基础的数据库管理员和技术人员。 使用场景及目标:帮助...
alter table TABLE_NAME shrink space compact; ``` - **重置高水位,此时不能有DML操作**: ```sql alter table TABLE_NAME shrink space; ``` - **整理表并重置高水位**: ```sql alter table TABLE_NAME...
ALTER TABLE table_name SHRINK SPACE KEEP INDEX; ``` #### 解决高水位带来的空间问题 1. **SHRINK SPACE**:除了用于解决性能问题外,还可以使用`SHRINK SPACE`来回收未使用的空间,减少表的存储需求。 ```...
启用行移动后,当执行`ALTER TABLE SHRINK SPACE`时,Oracle会自动移动行到新的位置,从而重置高水位线。 - **收缩表空间**: ```sql ALTER TABLE table_name SHRINK SPACE; ``` 这条命令用于收缩表空间,即...
3. **使用`ALTER TABLE <table_name> SHRINK SPACE`命令**: - **命令格式**:`ALTER TABLE <table_name> SHRINK SPACE;` - **功能**:这个命令可以通过整理表中的数据,减少表所占用的空间,从而降低高水位。 - ...
SHRINK SPACE`等命令来重新组织数据,并释放不再使用的空间。 通过上述方法和技术的应用,可以有效地提升Oracle数据库的整体性能,并简化其管理复杂度。这对于任何需要处理大量数据的企业来说都是至关重要的。
通过 `ALTER DATABASE DATAFILE SHRINK SPACE` 或 `ALTER TABLE MOVE` 可以减少表空间占用的空间。 5. **设置表空间为只读或只写**: `ALTER TABLESPACE SET READ ONLY` 或 `ALTER TABLESPACE SET READ WRITE` ...
ALTER TABLE 表名 ADD (列说明列表) 例:为test表增加一列Age,用来存放年龄 sql>alter table test add (Age number(3)); 修改基表列定义命令如下: ALTER TABLE 表名 MODIFY (列名 数据类型) 例:将test...
一旦数据被删除,HWM并不会下降,除非使用如DBMS_REDEFINITION或ALTER TABLE ... MOVE等高级操作。这导致即使有大量空闲空间,数据文件也无法收缩,因为HWM不允许新数据插入到HWM以下的块中。 为了分析数据文件的...