Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1703177
  • 博文数量: 136
  • 博客积分: 10021
  • 博客等级: 上将
  • 技术积分: 3261
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-22 11:26
文章分类

全部博文(136)

文章存档

2010年(1)

2009年(26)

2008年(109)

我的朋友

分类: Oracle

2008-07-04 14:20:13

在 Oracle10g 中,可以使用 shrink 来收缩表,而在 Oracle9i 中,可以使用 move:
 
SQL> select * from v$version;
 
BANNER
--------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE    9.2.0.1.0       Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production
-- 创建测试表
SQL> create table test_yct as select * from dba_objects;
 
表已创建。
 
SQL> insert into test_yct select * from test_yct;
 
已创建29607行。
 
SQL> /
 
已创建59214行。
 
SQL> /
 
已创建118428行。
 
SQL> /
 
已创建236856行。
 
SQL> commit;
 
提交完成。
 
-- 查看表的数据量和存储空间大小
SQL> select count(*) from test_yct;
 
  COUNT(*)
----------
    473712
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             51
 
-- 删除部分数据,再次查看该表:存储空间不变。
SQL> delete test_yct where rownum < 400000;
 
已删除399999行。
 
SQL> commit;
 
提交完成。
 
SQL> select count(*) from test_yct;
 
  COUNT(*)
----------
     73713
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             51
-- move 该表,存储空间被收缩
SQL> alter table test_yct move;
 
表已更改。
 
SQL> select count(*) from test_yct;
 
  COUNT(*)
----------
     73713
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
              8
 
move 的原理,就是在该表空间上再开辟一个新的临时段,来重新装载一份这个表的数据,装载完毕后,再删除旧段。类似于 create table ... as select * from ...。所以要注意该表空间中有足够的空间来存储新的数据段。下面我测试一个空间不够的情况:
 
-- 创建表空间、用户,及测试表
SQL> create tablespace tp_movetest datafile 'd:\tp_movetest1.dbf' size 60m;
 
表空间已创建。
 
SQL> create user movetest identified by test default tablespace tp_movetest;
 
用户已创建
 
SQL> grant dba to movetest;
 
授权成功。
 
SQL> conn movetest/test
已连接。
SQL> create table test_yct as select * from dba_objects;
 
表已创建。
 
SQL> insert into test_yct select * from test_yct;
 
已创建29608行。
 
SQL> /
 
已创建59216行。
 
SQL> /
 
已创建118432行。
 
SQL> /
 
已创建236864行。
 
SQL> commit;
 
提交完成。
 
SQL> select count(*) from test_yct;
 
  COUNT(*)
----------
    473728
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             51
 
-- 删除数据:存储空间并没有收缩
SQL> delete test_yct where rownum < 300000;
 
已删除299999行。
 
SQL> commit;
 
提交完成。
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             51
 
-- 查看此时该表空间的剩余空间:大约剩余9M
SQL> select TABLESPACE_NAME,FILE_ID,BLOCK_ID,BYTES/1024/1024 "size(M)",BLOCKS,RELATIVE_FNO
  2  from dba_free_space where tablespace_name='TP_MOVETEST';
 
TABLESPACE_NAME                   FILE_ID   BLOCK_ID    size(M)     BLOCKS RELATIVE_FNO
------------------------------ ---------- ---------- ---------- ---------- ------------
TP_MOVETEST                               15       6537          8.9375       1144           15
 
-- 执行 move 失败:无法扩展临时段
SQL> alter table test_yct move;
alter table test_yct move
            *
ERROR 位于第 1 行:
ORA-01652: 无法通过128(在表空间TP_MOVETEST中)扩展 temp 段
 
-- 增大表空间,move 成功。
SQL> alter database datafile 'd:\tp_movetest1.dbf' resize 80m;
 
数据库已更改。
 
SQL> alter table test_yct move;
 
表已更改。
 
-- 表已被收缩
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             19
 
-- 查看表空间此时的剩余空间:旧段占用的51M空间被释放;新开辟的段占用了19M,剩余大约10M。
SQL> select TABLESPACE_NAME,FILE_ID,BLOCK_ID,BYTES/1024/1024 "size(M)",BLOCKS,RELATIVE_FNO
  2  from dba_free_space where tablespace_name='TP_MOVETEST';
 
TABLESPACE_NAME                   FILE_ID   BLOCK_ID    size(M)     BLOCKS RELATIVE_FNO
------------------------------ ---------- ---------- ---------- ---------- ------------
TP_MOVETEST                            15                 9           51         6528           15
TP_MOVETEST                            15             8969     9.9375         1272           1
阅读(2293) | 评论(2) | 转发(0) |
0

上一篇:Oracle10g - shrink

下一篇:AUL 恢复数据一例

给主人留下些什么吧!~~

hoolma2008-12-03 22:58:44

当然还有一个可能就是重复产生相同记录.

hoolma2008-12-03 22:57:58

SQL> insert into test_yct select * from test_yct; 已创建29607行。 这行有问题,我不知你是抄别人的还是自已做测试写出来,居然还有记录?