实验在vmware虚拟机64位的solaris操作系统,10g release 2环境实现
本例中使用到用户tj,tj用户使用表空间usertest,并有无限的配额。
bash-3.00$ isainfo
-vk
64-bit amd64 kernel
modules
bash-3.00$ uname
-a
SunOS sunos 5.10
Generic_142910-17 i86pc i386 i86pc
bash-3.00$ sqlplus / as
sysdba
SQL*Plus: Release 10.2.0.1.0
- Production on Sun Jan 8 19:32:01 2012
Copyright (c) 1982, 2005,
Oracle. All
rights reserved.
Connected to:
Oracle Database 10g
Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP
and Data Mining options
Connected.
首先查看数据库存储使用情况,这里使用到了脚本tspace.sql ,脚本内容不做介绍
sys@DB01>
@tspace
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.8125
4
96
67.79
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
.1875
0
100
100
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
399.9375
100
0
100
7 rows selected.
Elapsed:
00:00:00.03
1.首先测试alter table .. move 命令
sys@DB01>
conn tj/tj
Connected.
tj@DB01>
select * from tab;
no rows
selected
Elapsed:
00:00:00.08
本例大表的创建借助了tom的脚本。
tj@DB01> get
big_table.sql
1 create table
big_table
2 as
3 select rownum id,
a.*
4
from all_objects a
5
where 1=0
6 /
7 alter table big_table
nologging;
8 declare
9
l_cnt number;
10
l_rows number := &1;
11 begin
12
insert
13
into big_table
14
select rownum, a.*
15
from all_objects a
16
where rownum <= &1;
17
l_cnt := sql%rowcount;
18
commit;
19
while (l_cnt < l_rows)
20
loop
21
insert into big_table
22
select rownum+l_cnt,
23
OWNER, OBJECT_NAME, SUBOBJECT_NAME,
24
OBJECT_ID, DATA_OBJECT_ID,
25
OBJECT_TYPE, CREATED, LAST_DDL_TIME,
26
TIMESTAMP, STATUS, TEMPORARY,
27
GENERATED, SECONDARY
28
from big_table
29
where rownum <= l_rows-l_cnt;
30
l_cnt := l_cnt + sql%rowcount;
31
commit;
32
end loop;
33 end;
34 /
35 alter table big_table
add constraint
36 big_table_pk primary
key(id)
37 /
38 begin
39
dbms_stats.gather_table_stats
40
( ownname
=> user,
41
tabname
=> 'BIG_TABLE',
42
method_opt => 'for all indexed columns',
43
cascade
=> TRUE );
44 end;
45 /
46* select count(*)
from big_table;
47
创建一个拥有2000000数据的大表
tj@DB01>
@big_table
Table created.
Elapsed:
00:00:00.55
Table
altered.
Elapsed:
00:00:00.05
Enter value for 1:
2000000
old
3:
l_rows number := &1;
new
3:
l_rows number := 2000000;
Enter value for 1:
2000000
old
9:
where rownum <= &1;
new
9:
where rownum <= 2000000;
PL/SQL procedure
successfully completed.
Elapsed:
00:00:07.59
Table altered.
Elapsed:
00:00:19.69
PL/SQL procedure
successfully completed.
Elapsed:
00:00:03.07
COUNT(*)
----------
2000000
Elapsed:
00:00:00.08
打开另外一个窗口,观察表空间使用的情况,计算big_table的大小
$ sqlplus / as
sysdba
SQL*Plus: Release 10.2.0.1.0
- Production on Sun Jan 8 19:02:32 2012
Copyright (c) 1982, 2005,
Oracle. All
rights reserved.
Connected to:
Oracle Database 10g
Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP
and Data Mining options
sys@DB01>
@tspace
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.3125
4
96
82.55
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
193.9375
26
74
75.82
EXAMPLE
100
31.75
32
68
72.85
USERTEST 400
132.9375
33
67
100
7 rows
selected.
sys@DB01>
select 400-133 from dual;
400-133
----------
267
表的大小是267M。
回到第一个窗口,删除表中不同位置的一些数据,模拟表碎片的状况
tj@DB01>
delete from big_table where id>=100000 and
id<=400000;
300001 rows
deleted.
Elapsed:
00:00:17.04
tj@DB01>
commit;
Commit complete.
Elapsed:
00:00:00.02
tj@DB01>
delete from big_table where id>=800000 and
id<=1200000;
400001 rows
deleted.
Elapsed:
00:01:03.56
tj@DB01>
delete from big_table where id>=1700000;
300001 rows
deleted.
Elapsed:
00:00:29.02
tj@DB01>
commit;
Commit complete.
Elapsed:
00:00:00.04
观察第二个窗口,看数据删除以后,表空间的存储使用情况。发现并没有什么变化,delete语句不会释放存储。
sys@DB01>
@tspace
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
1.4375
0
100
70.14
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
132.9375 33
67
100
7 rows selected.
执行alter table
..move命令,计算命令需要时间。
tj@DB01>
alter table big_table move;
Table
altered.
Elapsed:
00:00:18.85
在执行过程中,在第二个窗口观察,表空间使用情况
sys@DB01>
@tspace
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
1.3125
0
100
73.4
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
60.9375 15
85
100
7 rows
selected.
sys@DB01>
/
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
1.3125
0
100
73.4
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
12.9375
3
97
100
7 rows selected.
sys@DB01>
/
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5 2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
1.3125
0
100
73.4
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
12.9375
3
97
100
7 rows
selected.
sys@DB01>
/
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
1.3125
0
100
73.4
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
244.9375 61
39
81.84
7 rows selected.
sys@DB01>
select 400-244.9375 from dual;
400-244.9375
------------
155.0625
通过以上一段查询结果我们发现,在执行move命令过程当中,表空间的空闲空间会越来越少,在本例中当剩余空间到12.9375时,move操作最终完成,并最终释放空间,表在执行move操作后,表的大小由267M缩小到155M(也就是说有267-155=112M的碎片空间)。
move操作的完成需要额外的表空间存储来实现,但这个大小并不是表的大小的1倍,而是根据表上的碎片空间来决定,碎片空间越大,需要的表空间上额外的空间就会越少。当然对于特别大的表,建议表做分区,对每个分区单独move这样时间和空间需求都可以进一步控制。
2.接下来测试alter table.. shrink space操作,要求表空间是ASSM管理。为了进行比较,所做的操作一致。
tj@DB01>
tj@DB01> drop
table big_table purge;
Table
dropped.
Elapsed:
00:00:02.76
tj@DB01>
@big_table
Table
created.
Elapsed:
00:00:00.20
Table
altered.
Elapsed:
00:00:00.03
Enter value for 1:
2000000
old
3:
l_rows number := &1;
new
3:
l_rows number := 2000000;
Enter value for 1:
2000000
old
9:
where rownum <= &1;
new
9:
where rownum <= 2000000;
PL/SQL procedure
successfully completed.
Elapsed:
00:00:08.97
Table
altered.
Elapsed:
00:00:15.88
PL/SQL procedure
successfully completed.
Elapsed:
00:00:03.46
COUNT(*)
----------
2000000
Elapsed:
00:00:00.07
在另外一个窗口观察,表的大小还是267M。
sys@DB01>
@tspace
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
1.1875
0
100
77.17
EXAMPLE
100
31.75 32
68
72.85
USERTEST
400
132.9375
33
67
100
7 rows
selected.
回到到第一个窗口,开始删除数据
tj@DB01> delete from big_table
where id>=100000 and
id<=400000;
300001 rows
deleted.
Elapsed:
00:00:19.81
tj@DB01>
delete from big_table where id>=800000 and
id<=1200000;
400001 rows
deleted.
Elapsed:
00:00:28.84
tj@DB01>
commit;
Commit
complete.
Elapsed:
00:00:00.03
tj@DB01>
delete from big_table where id>=1700000;
300001 rows
deleted.
Elapsed:
00:00:36.38
tj@DB01>
commit;
Commit complete.
Elapsed:
00:00:00.01
在第二个窗口观察,表空间没有任何变化
sys@DB01>
@tspace
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096 4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
1.1875
0
100
77.17
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
132.9375
33
67
100
7 rows
selected.
回到第一个窗口,执行shrink
space 操作,为了执行这个命令,首先把表的row
movement属性开启。
tj@DB01>
select table_name,row_movement from user_tables;
TABLE_NAME
ROW_MOVE
------------------------------ --------
BIG_TABLE
DISABLED
Elapsed:
00:00:00.11
tj@DB01>
alter table big_table enable row movement;
Table altered.
Elapsed:
00:00:00.07
tj@DB01>
alter table big_table shrink space;
Table
altered.
Elapsed:
00:03:40.39
在第一个窗口执行命令的过程中,在第二个窗口观察表空间存储的变化
sys@DB01>
@tspace
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
90.3125
12
88
38.14
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
132.9375 33
67
100
7 rows
selected.
sys@DB01>
sys@DB01>
sys@DB01>
/
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
82.3125
11
89
37.49
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
132.9375
33
67
100
7 rows selected.
sys@DB01>
/
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
74.3125
10
90
36.69
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
132.9375 33
67
100
7 rows selected.
sys@DB01>
/
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
74.3125
10
90
36.69
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
132.9375
33
67
100
7 rows selected.
sys@DB01> /
Tablespace
Total Size
Free Size Pct
Free Pct
Used
FSFI
------------ ----------
---------- ---------- ---------- ----------
USERDATA
4096
4095.9375
100
0
82.77
SYSAUX
250
10.25
4
96
82.8
USERS
5
2
40
60
100
SYSTEM
740
266.5625
36
64
100
UNDOTBS1
750
.3125
0
100
100
EXAMPLE
100
31.75
32
68
72.85
USERTEST
400
254.5625 64
36
60.77
7 rows selected.
在以上的结果中,我们发现在命令执行过程当中,表的存储空间并没有任何变化,当命令执行完成后,存储空间释放。
综合以上分析,move操作需要使用额外的表空间存储,但是速度更快(本例中
Elapsed:
00:00:18.85)
shrink space操作,不需要任何额外的空间,但是速度要慢上很多(本例中
Elapsed:
00:03:40.39)
不建议在业务高峰时使用move和shrink space命令,move操作会锁住表,这样其他并发的用户在表上执行的DML语句会产生等待。shrink操作可以把他理解成内部的DML语句操作,所以不会对表生成排他锁(只在调整高水位线的时候会产生表的排他锁),其他用户的DML语句可以照常执行,建议如果非要在业务高峰期操作,为了不影响其他用户可以考虑使用
shrink space命令。
可以把shrink命令分解:
1.只压缩空间不调整水位线
在业务繁忙时可以执行。
alter table
big_table shrink space compact;
2.调整水位线 会产生锁,可以在业务比较少的时候执行,oracle 会记住1步骤中的操作,只调整水位线。
alter
table big_table shrink
space;
move命令会影响到表上的索引,索引需要rebuild。
shrink命令,oracle会维护索引,不用我们考虑。