alter table move和 shrink space

本文介绍了Oracle中的ALTER TABLE MOVE和SHRINK SPACE操作,用于收缩段、消除空间碎片。ALTER TABLE MOVE会锁表并使索引失效,需要重建;而SHRINK SPACE在不影响业务的情况下能进行空间整理。两者的区别在于收缩限制和对索引的影响。在自动段空间管理的表空间中,SHRINK SPACE还可用于收缩索引。实验验证了两者的不同效果。
摘要由CSDN通过智能技术生成

参考文章:
http://www.2cto.com/database/201201/117275.html
http://blog.csdn.net/huangchao_sky/article/details/8700394
http://www.2cto.com/database/201201/117816.html
http://www.cnblogs.com/Cratical/archive/2010/08/24/1806948.html

切记:
move操作会锁表。
如果是很小的表,可以在线做。
如果是大表一定要注意,会长时间锁表,只能查询,影响正常业务运行。
move操作会使索引失效,一定要rebuild。
(在这方面吃过亏,所以记得很清楚。)

shrink操作期间可以对表进行增删改查。

简单总结对比

alter table table_name move和alter table table_name shrink space都可以用来收缩段,消除部分行迁移(Row Migration) 消除空间碎片,使数据更紧密,降低高水位HWM。
但是有如下区别:

  1. 使用alter table move,会把表格最多收缩到创建表格时的storage子句指定的初始大小,使用alter table shrink space,则不受此限制。
    (也就是说,如果创建表的DDL语句指明了初始大小为10M,数据量最大时占用15M,假定现在表的数据只占用了2M,那么move操作只能将表占用空间减小到10M,HWM为2M。而shrink可以将表的空间占用和HWM都降到2M。)
    (如果想是用move的方式收缩到初始化大小以下,需要在alter move语句中加初始化参数。)
  2. 使用alter table move之后,索引会无效,需要重建,因为move操作会改变一些记录的ROWID,所以MOVE之后索引会变为无效,需要REBUILD。使用alter table shrink space,则不会使索引无效,因为使用shrink space时,索引会自动维护。
  3. 只能在表格所在的表空间是自动段空间管理(创建tablespace时指定了SEGMENT SPACE MANAGEMENT AUTO子句)的时候,才能使用alter table shrink space。
  4. 如果在业务繁忙时做压缩,可以使用alter table shrink space compact来对表格进行碎片整理,而不调整HWM,之后再次调用alter table shrink space来释放空间。
  5. 可以使用alter table shrink space cascade来同时对索引都进行收缩,这等同于同时执行alter index shrink space。
  6. alter table t move和alter table t shrink space都可以用来消除行链接(Row Chaining)和行迁移(Row Migration)。
    为此需要先建立chained_rows表格。
    首先执行$ORACLE_HOME/RDBMS/ADMIN/utlchain.sql脚本建立chained_rows表格,
    然后执行analyze table xxx list chained rows [into chained_rows],如果存在行链接或者行迁移,查询chained_rows就能找到发生了行链接或者行迁移的行。
    然后执行alter table move或shrink space,然后再次查看chained_rows表即可验证行链接是否消失。

下面做实验验证一下:

第一个区别

drop table TEST_MOVE;
CREATE TABLE TEST_MOVE
   (IP VARCHAR2(30 BYTE), 
    CHECKDATE VARCHAR2(30 BYTE), 
    CMDTYPE VARCHAR2(50 BYTE), 
    CONFIGDETAIL VARCHAR2(500 BYTE)
   ) SEGMENT CREATION IMMEDIATE 
  STORAGE(INITIAL 10485760 NEXT 1048576)
  TABLESPACE USERS;

SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST_MOVE';

SEGMENT_NAME                      EXTENTS     BLOCKS       INIT
------------------------------ ---------- ---------- ----------
TEST_MOVE                               3       1280         10
--TEST表初始分配了10M的空间,可以看到有10个EXTENTS,1280个BLOCKS。USER_TABLES视图显示有0个使用的BLOCKS,1280个空闲BLOCKS,即该10M空间内的BLOCK都还没被ORACLE”格式化”。

SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST_MOVE';

TABLE_NAME                         BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ------------
TEST_MOVE

--向表中插入数据
SQL> insert into TEST_MOVE select * from information;

122513 rows created.

SQL> analyze table TEST_MOVE compute statistics;

Table analyzed.

SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST_MOVE';

SEGMENT_NAME                      EXTENTS     BLOCKS       INIT
------------------------------ ---------- ---------- ----------
TEST_MOVE                               3       1280         10

SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST_MOVE';

TABLE_NAME                         BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ------------
TEST_MOVE                            1006          274

--插入数据后,分配的空间仍不变,因为10个EXTENTS还没使用完。显示使用了1006个BLOCKS,空闲274个BLOCKS。这时候的1006 BLOCKS即是高水位线。

SQL> commit;

Commit complete.

SQL> select count(*) from test_move;

  COUNT(*)
----------
    122513

SQL> delete from test_move  where rownum<=
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值