Shrink space合并表的碎片
C:\Documents and Settings\Administrator>sqlplus greatfinish/finish
连接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
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;
Unformatted Blocks ..................... 0
FS1 Blocks (0-25) ..................... 0
FS2 Blocks (25-50) ..................... 0
FS3 Blocks (50-75) ..................... 0
FS4 Blocks (75-100)..................... 0
Full Blocks ..................... 32
Total Blocks............................ 40
Total Bytes............................. 327,680
Total MBytes............................ 0
Unused Blocks........................... 3
Unused Bytes............................ 24,576
Last Used Ext FileId.................... 4
Last Used Ext BlockId................... 1,993
Last Used Block......................... 5
Unformatted Blocks ..................... 0
FS1 Blocks (0-25) ..................... 0
FS2 Blocks (25-50) ..................... 31
FS3 Blocks (50-75) ..................... 0
FS4 Blocks (75-100)..................... 0
Full Blocks ..................... 1
Total Blocks............................ 40
Total Bytes............................. 327,680
Total MBytes............................ 0
Unused Blocks........................... 3
Unused Bytes............................ 24,576
Last Used Ext FileId.................... 4
Last Used Ext BlockId................... 1,993
Last Used Block......................... 5
Unformatted Blocks ..................... 0
FS1 Blocks (0-25) ..................... 0
FS2 Blocks (25-50) ..................... 0
FS3 Blocks (50-75) ..................... 0
FS4 Blocks (75-100)..................... 0
Full Blocks ..................... 22
Total Blocks............................ 32
Total Bytes............................. 262,144
Total MBytes............................ 0
Unused Blocks........................... 6
Unused Bytes............................ 49,152
Last Used Ext FileId.................... 4
Last Used Ext BlockId................... 2,025
Last Used Block......................... 2
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;
Unformatted Blocks ..................... 0
FS1 Blocks (0-25) ..................... 0
FS2 Blocks (25-50) ..................... 0
FS3 Blocks (50-75) ..................... 0
FS4 Blocks (75-100)..................... 0
Full Blocks ..................... 32
Total Blocks............................ 40
Total Bytes............................. 327,680
Total MBytes............................ 0
Unused Blocks........................... 3
Unused Bytes............................ 24,576
Last Used Ext FileId.................... 4
Last Used Ext BlockId................... 1,993
Last Used Block......................... 5
Unformatted Blocks ..................... 0
FS1 Blocks (0-25) ..................... 0
FS2 Blocks (25-50) ..................... 31
FS3 Blocks (50-75) ..................... 1
FS4 Blocks (75-100)..................... 0
Full Blocks ..................... 0
Total Blocks............................ 40
Total Bytes............................. 327,680
Total MBytes............................ 0
Unused Blocks........................... 3
Unused Bytes............................ 24,576
Last Used Ext FileId.................... 4
Last Used Ext BlockId................... 1,993
Last Used Block......................... 5
Unformatted Blocks ..................... 0
FS1 Blocks (0-25) ..................... 1
FS2 Blocks (25-50) ..................... 2
FS3 Blocks (50-75) ..................... 0
FS4 Blocks (75-100)..................... 12
Full Blocks ..................... 17
Total Blocks............................ 40
Total Bytes............................. 327,680
Total MBytes............................ 0
Unused Blocks........................... 3
Unused Bytes............................ 24,576
Last Used Ext FileId.................... 4
Last Used Ext BlockId................... 1,993
Last Used Block......................... 5
2 (select dbms_rowid.rowid_block_number(rowid) block_num from t)
3 group by block_num;
---------- ----------
1956 352
1957 352
1958 351
1959 346
1960 351
1961 349
1962 349
1963 350
1964 351
1965 352
1966 353
1967 354
1968 350
1970 347
1971 348
1972 353
1973 348
1974 288
1975 212
1976 210
Oracle 10g
语法:
alter table <table_name> shrink space [ <null> | compact | cascade ];
alter table <table_name> shrink space compcat;
收缩表,但会保持 high water mark; (这怎么理解?相当于没回缩?)
alter table <table_name> shrink space;
收缩表,降低 high water mark;
alter table <table_name> shrink space cascade;
收缩表,降低 high water mark,并且相关索引也要收缩一下下。
shrink space compcat;
相当于把块中数据打结实了。没有变动hwm。
方法一:
Export/Truncate/Import
方法二:
alter table table_name move; alter index index_name rebuild;
这两种方法,哪种更好?我个人觉得方法二更方便。
如果方便的話,就用第二种。個人一直用的第二种方式!
前面提到oracle在10g已有專用的命令來做此動作了,如下:
alter table table_name shrink space;
後面還有兩個參數:cascade,compact;
compact:加此參數是爲了黨系統負載比較大時,做此動作可以減小性能影響。在負載比較輕時,在作一次alter table table_name shrink space;就可以了。
cascade:加上此參數會及聯shrink table上的索引,也相當如rebuild index; 也就相當於你上面在9i裏處理此問題的第二种方式了!
所以第二种方式是完全可行的,只是要關注做此動作時對性能的影響。一般在系統負載比較輕時做此動作。另rebuild online時,會lock table。此時會影響系統dml操作,因此可以在語句后加online來降低影響,但會增加rebuil時間。總計,均衡當前狀況,來採取最合理的方式!
我发现一个问题:
如果 执行 ALTER TABLE xxx MOVE; 后 还没有来的及执行 ALTER INDEX xxx REBUILD;
就有人对 该表进行了查询或更新,
那么就会报错;
有没有办法在ALTER TABLE xxx MOVE的时候,该表还能正常被使用,这样就不用担心用在执行上面那个批量整理脚本的时候,数据库一些表访问会报错;
因爲alter table ... move,會使得此表上的索引失效,此時,會使得利用索引訪問此表的sql語句報錯。因此,此動作一般是不會經常做的,也沒這個必要,也不會寫在腳本裏自動執行,還是在系統負載較輕時,手動維護比較好!
另做此動作后,注意重新分析下此表及對應索引!
补充:ALTER TABLE xxx MOVE将导致rowid改变,而索引是根据rowid来访问的,所以会出错。
表
1:普通表
shrink必须开启行迁移功能。
alter table table_name enable row movement ;
保持HWM
alter table table_name shrink space compact;
回缩表与HWM
alter table table_name shrink space;
回缩表与相关索引
alter table table_name shrink space cascade;
回缩索引
alter index index_name shrink space;
Sql脚本
select'alter table '||table_name||' enable row movement;'||chr(10)||'alter table '||table_name||' shrink space;'||chr(10)fromuser_tables;
select'alter index '||index_name||' shrink space;'||chr(10)fromuser_indexes;
2:分区表的处理
进行shrink space时 发生ORA-10631错误.shrink space有一些限制.
在表上建有函数索引(包括全文索引)会失败。
sql脚本
select 'alter table '||segment_name||' modify subpartition '||partition_name||' shrink space;'||chr(10) from user_segments where segment_type='TABLE SUBPARTITION'
脚本
执行方法cmd
C:"cd到放置两个文件的文件夹
Sqlplus username/password@oracle_sid
Sql>@sp.sql
@@sp.sql
set heading off
set feedback off
set term off
set page off
set trimspool on
spool a.log
@a.sql
spool off
@@a.log /*慎重,估计好执行时间再执行,也可以手动执行脚本*/
Exit
@@a.sql
select 'alter table '||table_name||' enable row movement;'||chr(10)||'alter table '||table_name||' shrink space;'||chr(10) from user_tables where table_name ;
select 'alter index '||index_name||' shrink space;'||chr(10) from user_indexes where uniqueness='NONUNIQUE' ;
select 'alter table '||segment_name||' modify subpartition '||partition_name||' shrink space;'||chr(10) from user_segments where segment_type='TABLE SUBPARTITION' ';