查看表的碎片程序可以通过我的这篇博客来查询http://blog.csdn.net/gguxxing008/article/details/6858579
查到需要清理的碎片后,可以用如下两种方式来清理碎片:
alter table xxx shrink space 和 alter table xxx move
move命令是将数据从原来的段移到目标段的命令。
[move命令]
SQL> alter table emp move;
ORA-01652: unable to extend temp segment by 8 in tablespace AUTOSEG_TSTAUTOSEG_TST表空间没有足够的空闲空间。
SQL> select f.tablespace_name,d.file_name,f.bytes/1024 KBytes,f.blocks,d.autoextensible
from dba_free_space f,dba_data_files d,dba_tables t
where f.tablespace_name = d.tablespace_name
and f.tablespace_name = t.tablespace_name
and t.owner='SCOTT'
and t.table_name='EMP';
TABLESPACE_NAME FILE_NAME KBYTES BLOCKS AUTOEXT--------------- ---------------------------------------- ------- ------- -------AUTOSEG_TST /export/home/ora10g/oradata/AUTOSEG1.DBF 64 8 NO
[shrink命令]
即使对象所在表空间几乎没有空闲空间,shrink命令也能执行。
SQL> alter table emp shrink space; --收缩空间并降低HWM,compact参数收缩空间不降低HWM
Table altered.
# 差异点1. 不需要重建index
[move命令]
table具有主键index的时候,如果使用move命令就必须重建index。
SQL> alter table dept move;Table altered.
SQL> select owner,index_name,status from dba_indexes
where table_owner='SCOTT' and table_name='DEPT';
OWNER INDEX_NAME STATUS----- ---------- --------SCOTT PK_DEPT UNUSABLE ←(不能使用index)
SQL> select /*+ index(dept pk_dept) */ * from dept where rownum=1;ORA-01502: index 'SCOTT.PK_DEPT' or partition of such index is in unusable state
执行move命令之后无法使用index,所以无法利用index查找。要解决这个问题让index恢复可以使用的状态,必须对index进行rebuild。
SQL> alter index pk_dept rebuild;
Index altered.
SQL> select /*+ index(dept pk_dept) */ * from dept where rownum=1;
DEPTNO DNAME LOC---------- -------------- ------------- 10 ACCOUNTING NEW YORK
[shirnk命令]
执行shrink命令的时候就不需要rebuild index。
SQL> alter table dept shrink space;
Table altered.
SQL> select /*+ index(dept pk_dept) */ * from dept where rownum=1;
DEPTNO DNAME LOC---------- -------------- ------------- 10 ACCOUNTING NEW YORK
SQL> select owner,index_name,status from dba_indexes where table_owner='SCOTT'and table_name='DEPT';
OWNER INDEX_NAME STATUS----- ---------- --------SCOTT PK_DEPT VALID ←(index可以使用)
# 差异点2. cascade选项
前面用shrink命令让dept表缩小,cascade命令会让相关的pk_dept索引也同时缩小。
[shrink命令 -没有选项-] --dept表shrink之前
SQL> select owner,segment_name,bytes,blocks,extents from dba_segments where segment_name = 'PK_DEPT';
OWNER SEGMENT_NAME BYTES BLOCKS EXTENTS
----- ------------ ---------- ---------- ----------
SCOTT PK_DEPT 18874368 2304 33
SQL> alter table dept shrink space;
Table altered.
--dept表shrink之后
SQL> select owner,segment_name,bytes,blocks,extents from dba_segments where segment_name = 'PK_DEPT';
OWNER SEGMENT_NAME BYTES BLOCKS EXTENTS
----- ------------ ---------- ---------- ----------
SCOTT PK_DEPT 18874368 2304 33
大家可以看到相关的pk_dept索引缩小了。
结论
我们已经针对Oracle 10g新功能shrink命令进行两次检验,主要都是介绍shrink命令的优点,下面追加相关限制事项。
1.无法解除行迁移
2.必须是local管理的自动段管理
3.不可以是下面的段:
-集群(cluster)、集群化表
-包含long列的物件
-LOB段
-包含函数索引(function index)的表
From itpub:
1、move可以解决CHAINED_ROW 和 MIGRATION 的问题
shrink不行
2、shrink table 对index不会有影响
实际是做insert,delete ,因此undo空间耗用很多,归档模式的话会产生大量的redo,如果可以停应用,用move效率高的多的多
3、move table之后,rowid已改变,index需要重建
实际是做create table as ,因此undo空间耗用很少
所以move的速度会比shrink快很多