Oracle Shrink Table

從10g開始,oracle開始提供Shrink的命令,假如我們的表空間中支持自動段空間管理 (ASSM),就可以使用這個特性縮小段,即降低HWM。這裏需要強調一點,10g的這個新特性,僅對ASSM表空間有效,否則會報 ORA-10635: Invalid segment or tablespace type。



如果經常在表上執行DML操作,會造成數據庫塊中數據分佈稀疏,浪費大量空間。同時也會影響全表掃描的性能,因爲全表掃描需要訪問更多的數據塊。從oracle10g開始,表可以通過shrink來重組數據使數據分佈更緊密,同時降低HWM釋放空閒數據塊。



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釋放空閒數據塊。



shrink必須開啓行遷移功能。



alter table table_name enable row movement ;



注意:alter table XXX enable row movement語句會造成引用表XXX的對象(如存儲過程、包、視圖等)變爲無效。執行完成後,最好執行一下utlrp.sql來編譯無效的對象。

============================================================================================


utlrp.sql and utlprp.sql
The utlrp.sql and utlprp.sql scripts are provided by Oracle to recompile all invalid objects in the database. They are typically run after major database changes such as upgrades or patches. They are located in the $ORACLE_HOME/rdbms/admin directory and provide a wrapper on the UTL_RECOMP package. The utlrp.sql script simply calls the utlprp.sql script with a command line parameter of "0". The utlprp.sql accepts a single integer parameter that indicates the level of parallelism as follows:

0 - The level of parallelism is derived based on the CPU_COUNT parameter.
1 - The recompilation is run serially, one object at a time.
N - The recompilation is run in parallel with "N" number of threads.
Both scripts must be run as the SYS user, or another user with SYSDBA, to work correctly.


============================================================================================

語法:



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



alter table <table_name> shrink space compcat;



收縮表,相當於把塊中數據打結實了,但會保持 high water mark;



alter table <tablespace_name> shrink space;



收縮表,降低 high water mark;



alter table <tablespace_name> shrink space cascade;



收縮表,降低 high water mark,並且相關索引也要收縮一下下。



alter index idxname shrink space;



回縮索引





1:普通表



Sql腳本,改腳本會生成相應的語句



select'alter table '||table_name||' enable row movement;'||chr(10)||'alter table '||table_name||' shrink space;'||chr(10)from user_tables;



select'alter index '||index_name||' shrink space;'||chr(10)from user_indexes;



2:分區表的處理



進行shrink space時 發生ORA-10631錯誤.shrink space有一些限制.



在表上建有函數索引(包括全文索引)會失敗。





Sql腳本,改腳本會生成相應的語句



select 'alter table '||table_name||' enable row movement;'||chr(10)||'alter table '||table_name||' shrink space;'||chr(10) from user_tables where ;



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' ';





示例





在oracle中可以使用alter table table_name shrink space收縮表,使用shrink有兩個前提條件:



1、表必須啓用row movement

2、表段所在表空間的段空間管理(segment space management)必須爲auto





實驗如下:



--建立一個segment space management auto表空間

SQL> create tablespace ts_auto datafile 'd:\ts_auto.dbf' size 100m extent management local segment space management auto;





--建議測試表

SQL> create table tb_auto tablespace ts_auto as select * from dba_objects;





--查看shrink前的塊數量

SQL> select blocks from dba_segments where segment_name='TB_AUTO';



BLOCKS

----------

768







--delete數據後,空間佔用沒有變化

SQL> delete from tb_auto;



已刪除49823行。

SQL> commit;



提交完成。



SQL> select blocks from dba_segments where segment_name='TB_AUTO';



BLOCKS

----------

768







--直接收縮,提示必須啓動row movement選項

SQL> alter table tb_auto shrink space;

alter table tb_auto shrink space

*

第 1 行出現錯誤:

ORA-10636: ROW MOVEMENT is not enabled

SQL> alter table tb_auto enable row movement;



表已更改。





--收縮成功,空間已經釋放

SQL> alter table tb_auto shrink space;



表已更改。



SQL> select blocks from dba_segments where segment_name='TB_AUTO';



BLOCKS

----------

8







--shrink不能在segment space management manaual的表空間的段上執行

SQL> create tablespace ts_manual datafile 'd:\ts_mannel.dbf' size 100m extent



management local segment space management manual;



表空間已創建。



SQL> select tablespace_name,segment_space_management from dba_tablespaces;



TABLESPACE_NAME SEGMEN

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

SYSTEM MANUAL

UNDOTBS1 MANUAL

SYSAUX AUTO

TEMP MANUAL

USERS AUTO

EXAMPLE AUTO

TS_AUTO AUTO

TS_MANUAL MANUAL



已選擇8行。



SQL> create table tb_manual tablespace ts_manual as select * from dba_objects;



表已創建。



SQL> alter table tb_manual shrink space

2 ;

alter table tb_manual shrink space

*

第 1 行出現錯誤:

ORA-10635: Invalid segment or tablespace type




本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/wh62592855/archive/2009/11/25/4873493.aspx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章