1.分析表

exec dbms_stats.gather_table_stats('BAAL','T',cascade==>true);
或者
analyze table t compute statistics;
select blocks,empty_blocks from dba_tables where table_name='';


2.用第一步得到的块数blocks的数目(高水位线的位置)跟如下SQL语句得到的(当前正在使用的块数)比较,从而可以看出高水位线下边是否有大量空间没被使用

SELECT COUNT (DISTINCT DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid)||DBMS_ROWID.ROWID_RELATIVE_FNO(rowid)) "Used" FROM T;
 
select  round((1-a.used/b.num_total)*100,0)  percent from
(SELECT COUNT (DISTINCT SUBSTR(rowid,1,15)) Used FROM &1) a,
(select blocks num_total from user_tables where table_name='&1') b;


3.如果空闲空间大于20%,则考虑回收高水位线,方法有:
在ORACLE中,执行对表的删除操作不会降低该表的高水位线。而全表扫描将始终读取一个段(extent)中所有低于高水位线标记的块。如果在执行删除操作后不降低高水位线标记,则将导致查询语句的性能低下。下面的方法都可以降低高水位线标记。

1.执行表重建指令 alter tabletable_namemove;
(在线转移表空间ALTER TABLE 。。。 MOVE TABLESPACE 。。。
ALTER TABLE 。。。 MOVE 后面不跟参数也行,
不跟参数表还是在原来的表空间,move后记住重建索引
如果以后还要继续向这个表增加数据,没有必要move,
只是释放出来的空间,只能这个表用,其他的表或者segment无法使用该空间
)

2.执行alter table table_name shrink space; 注意,此命令为Oracle 10g新增功能,再执行该指令之前必须允许行移动
alter table table_name enable row movement;
3.复制要保留的数据到临时表t,drop原表,然后rename临时表t为原表
4.emp/imp
5.alter   table  table_name  deallocate   unused
6.尽量truncate 吧