在实际的生产业务当中,delete不会释放表空间,但是可以重用,也就是插入可以填补空洞,当然现实应用中确实是存在经常删除很少插入的情况。如何收缩段,消除部分行迁移,消除空间碎片,使数据更紧密?我们自然会想到的是alter table move 与alter table shrink space。
► 提高空间的使用率。
► 提高语句执行过程中查询的效率。
♣可以收缩段,用来消除部分行迁移,消除空间碎片使数据更紧密;
♣执行过程都改变rowid的改变;
♣执行过程产生行级锁和表级锁;
♣移动高水位。
1. alter table move
♣ alter table move 省略了tablespace xxxx, 表示用户移到自己默认的表空间,因此当前表空间至少要是该表两倍大,在省略情况下操作大表move操作容易导致表空间撑满;
♣ alter table move过程中会导致索引失效,必须要考虑重新索引。
♣ 不会释放申请的空间,是在高水位以下(below HWM)的操作;
♣ 直接可以操作move。
2. shrink space
♣ shrink space过程不占用多余的空间,不消耗两倍表空间,不会导致表空间撑满;
♣ shrink space 过程自动维护索引,最后不需重建索引;
♣ 释放申请的空间,是在高水位以下(below HWM)和以上(above HWM)的操作;
♣ 不能直接操作,前提条件是被shrink的表启用row movement,表段所在表空间的段空间管理(segment space management)必须为auto。
1. 产生锁
表在move的过程,会产生一些锁TX、TM等来类型的锁,move动作前和move动作完成后,没有产生锁。
2. 索引失效
♣ 这个实验说明:除了知道alter table move命令可以释放空间(当然这语句最根本的作用还是移动表到不同的表空间去,这里只是借用它可以释放空间的一个特性)。
♣ 还要了解该动作会锁表直到命令结束,而且会导致索引失效,属于危险命令,建议千万不要在业务高峰期操作。
TEST表初始分配了10M的空间,可以看到有3个EXTENTS,1280个BLOCKS。USER_TABLES视图显示有0个使用的BLOCKS,1280个空闲BLOCKS,即该10M空间内的BLOCK都还没被ORACLE”格式化”。
1. 插入测试数据
插入10W条数据后,分配的空间仍不变,因为3个EXTENTS还没使用完。显示使用了174个BLOCKS,空闲1106个BLOCKS。这时候的174个BLOCKS即是高水位线。
2. 删除部分记录
删掉一半数据后,仍然显示使用了174个BLOCKS,高水位没变。但查询真正使用的BLOCK数只有77个。所DELETE操作是不会改变HWM的。
3. 删除记录后move表
MOVE之后,HWM降低了,空闲块也上去了,但是分配的空间并没有改变,仍然是1280个BLOCKS。
4. 删除记录后shrink表
♣ MOVE并不算真正意义上的压缩空间,只会压缩HWM以下的空间,消除碎片。而SHRINK SPACE真正做到了对段的压缩,包括初始分配的也压了,所以它是blow and above HWM操作。
♣ 两个都可以提高空间使用率,语句执行过程中,减少数据块的扫描次数,提高语句的查询效率。
♣ 使用move时,会改变一些记录的ROWID,所以MOVE之后索引会变为无效,需要REBUILD。同时move表需要2倍的表空间,而shrink不需要
♣ 使用shrink space时,索引会自动维护。如果在业务繁忙时做压缩,可以先 shrink space compact,来压缩数据而不移HWM,
等到不繁忙的时候再shrink space来移动HWM。
♣ 索引也是可以压缩的,压缩表时指定Shrink space cascade会同时压缩索引,也可以alter index xxx shrink space来压缩索引。
♣ shrink space需要在表空间是自动段空间管理的,所system表空间上的表无法shrink space。