收缩段消除空间碎片的方法有两种:
方法1:使用 Move 命令
alter table table_name move
注意:
1) move 操作会锁表。(如果是很小的表,可以在线做。如果是大表一定要注意,会长时间锁表,只能查询,影响正常业务运行)
2) move 操作会使索引失效,一定要 rebuild。(因为move操作会改变一些记录的ROWID,所以MOVE之后索引会变为无效,需要REBUILD)
方法2:使用 Shrink Space 命令
alter table table_name shrink space [<null>|cpmpact|cascade]
前提条件:
1) 必须启用行记录转移(enable row movement)
2) 仅仅适用于堆表,且位于自动段空间管理的表空间(堆表包括:标准表,分区表,物化视图容器,物化视图日志表)
优点:
提高缓存利用率,提高OLTP的性能
减少磁盘I/O,提高访问速度,节省磁盘空间
段收缩是在线的,索引在段收缩期间维护,不要求额外的磁盘空间加参数
cascade:缩小表及其索引,并移动高水位线,释放空间
compact:仅仅是缩小表和索引,并不移动高水位线,不释放空间
如果在业务繁忙时做压缩,
可以使用 alter table shrink space(compact 来对表格进行碎片整理,而不调整高水位线,之后再次调用 alter table table_name shrink space 来释放空间),
或者使用 alter table table_name shrink space(cascade 来同时对索引都进行收缩,这等同于同时执行 alter index idxname shrink space)。
参数 compact 和 cascade 详解
1) campact 参数。如果使用了该参数,oracle会清除段中的碎片并压缩表中的行。
数据库不会理解调整HWM也不会立即释放这些空间。你必须另外再执行一次alter table ....shrink space语句来完成该操作。
这个语句在你在用两个短的操作而不是一个长的操作来完成压缩表所占的空间的情况下是有用的。
对于索引或者索引组织的表使用ALTER [INDEX | TABLE] ... SHRINK SPACE COMPACT和使用ALTER [INDEX | TABLE ... COALESCE是等效的 shrink语句可以级联压缩。相对于 coalesce操作压缩尺度更大,也更能提高性能。如果你不想释放无用的空间,你可以使用coalesce语句。
2) cascade参数。如果使用了该参数,oracle在该表的独立的对象上(包括索引组织表的索引)执行同样的压缩操作。
shrink 命令注意事项
(1)不能和其他alter table语句合并到一起,不能将该语句用于簇、簇表和任何有long类型列的表。
(2)段压缩不支持有函数索引、域索引和bitmap join index的表
(3)该语句不会压缩映射表盒索引组织表,即使你使用cascade字句
(4)不能在压缩表上使用该语句
(5)不能压缩on commit的物化视图的主表。压缩操作之后基于rowid的物化视图必须被重建。
关于启用行记录转移
alter table table_name enable row movement;
练习操作
/* 查看数据表大小 */ select UT.table_name, x.TABLE_SIZE from user_tab_comments ut, (select Segment_Name, Sum(bytes) / 1024 / 1024 / 1024 as "TABLE_SIZE" From User_Extents Group By Segment_Name) x where ut.table_type = 'TABLE' and ut.table_name = x.Segment_Name(+) order by x.TABLE_SIZE desc;
/* 释放空间 */ truncate table table_name_001; alter table table_name_001 enable row movement; alter table table_name_001 shrink space;
参考资料
https://blog.csdn.net/weixin_30819373/article/details/116324228
https://blog.csdn.net/nangy2514/article/details/107628862
https://www.cnblogs.com/klb561/p/10995016.html