一、前言
在oracle中如果有一张表有一亿条数据,使用delete语句删除了其中的5000万条数据,那么此时表段的高水位线hwm是不会回收的,也就是该表的空间不会释放,仅仅是段内数据变稀疏了;那么如何解决此类问题?
二、验证
2.1 查询表中的段空间占用情况(总的表占用了1399586816 byte的空间)
select s.BYTES/1024/1024,s.* from user_segments s where lower(s.segment_name) = 'tbm_importdata'
2.2 执行delete 语句删除表中数据
delete tbm_importdata;--这里的演示,将数据全部删除
2.3 再次查询表段占用空间大小(表空占用空间没有释放)
2.4 进行表空间回收处理,降低高水位线hwm
由于需要移动行数据,数据的rowid会发生变化,所以需要设置表的row movement属性:
1.alter table tbm_importdata enable row movement;--开启行迁移功能。
2.alter table tbm_importdata shrink space cascade;--收缩表并降低hwm,并且回收相应的索引。
由于我们删除了大量的数据 ,相应的索引也进行了删除,这时需要对索引进行收缩。
alter index idxname shrink space;
注意:shrink table只会针对assm(自动段空间管理)的表有用,否则会报: ORA-10635: Invalid segment or tablespace type。
注意:
alter table tablename_max enable row movement语句会造成引用表tbm_importdata的对象(如存储过程、包、视图等)变为无效。执行完成后,最好执行一下utlrp.sql来编译无效的对象。
由于是通过DML操作进行的,会产生大量redo,注意archivelog目录的空间大小问题;同时undo表空间也会暴增。
三、额外扩展
alter table tablename_max shrink space compact;--(可以在压缩期间进行DML操作和查询) ,收缩表,不会降低hwm
alter table tablename_max shrink space; --( 调整HWM时将阻塞DML操作),收缩表,并且降低hwm