概述
从 8i开始,Oracle 开始提供 move 命令。通常使用这个命令将一个 table segment从一个tablespace 移动到另一个 tablespace。
move实际上是在block之间物理地copy数据,可以通过这种方式来降低table的HWM 。
下面主要通过一个实验来看看 move是如何移动数据的。
1、创建 table TEST_HWM 和测试数据
create table TEST_HWM (id int ,name char(2000)) tablespace hwm;
--往 table TEST_HWM 中 insert以下数据:
insert into TEST_HWM values (1,'aa');insert into TEST_HWM values (2,'bb');insert into TEST_HWM values (2,'cc');insert into TEST_HWM values (3,'dd');insert into TEST_HWM values (4,'ds');insert into TEST_HWM values (5,'dss');insert into TEST_HWM values (6,'dss');insert into TEST_HWM values (7,'ess');insert into TEST_HWM values (8,'es');insert into TEST_HWM values (9,'es');insert into TEST_HWM values (10,'es');
2、查看这个 table 的 rowid、block 的 id 和信息:
select rowid,id,name from TEST_HWM;
select EXTENT_ID,FILE_ID,RELATIVE_FNO,BLOCK_ID,BLOCKS from dba_extents where segment_name='TEST_HWM' ;
PS:row id 在磁盘上需要 10 个字节的存储空间并使用18 个字符来显示,它包含下列组件:
1)数据对象编号:每个数据对象如表或索引在创建时分配,并且此编号在数据库中是惟一的。2)相关文件编号:此编号对于一个表空间中的每个文件是惟一的。3)块编号:表示包含此行的块在文件中的位置。4)行编号:标识块头中行目录位置的位置。
在内部数据对象编号需要 32 位,相关文件编号需要 10 位,块编号需要 22 位,行编号需要16 位,加起来总共是 80 位或 10 个字节,row id 使用以 64 为基数的编码方案来显示。
该方案将 6个位置用于数据对象编号,3 个位置用于相关文件编号,6 个位置用于块编号,3 个位置用于行编号。以 64 为基数的编码方案使用字符 A ~Z、a~z、0~9、+和/共 64 个
字符,如下例所示:
AAAVqH AAJ AAAA5/ AAA
在这里,AAAVqH是数据对象编号,AAJ是相关文件编号,AAAA5/是块编号,AAA是行编号。
那么,根据数据的 rowid,可以看出这11行数据分布在 AAAA5/、AAAA6A、AAAA6B、AAAA6F这4个 block 中。
3、从table TEST_HWM 中delete 一些数据:
delete from TEST_HWM where id = 2;delete from TEST_HWM where id = 4;delete from TEST_HWM where id = 3;delete from TEST_HWM where id = 7;delete from TEST_HWM where id = 8;delete from TEST_HWM where id = 9;
4、查看这个 table 的 row id、block 的 id 和信息
select rowid,id,name from TEST_HWM;
select EXTENT_ID,FILE_ID,RELATIVE_FNO,BLOCK_ID,BLOCKS from dba_extents where segment_name='TEST_HWM' ;
可以看到,数据的 rowid 没有发生改变,根据数据的 rowid,可以看出这 4 行数据依然分布在AAAA5/、AAAA6A、AAAA6B、AAAA6F这 4 个 block 中。
5、针对TEST_HWM 进行 move 的操作,然后观察 rowid 和 blockid
alter table TEST_HWM move;select rowid,id,name from TEST_HWM;select EXTENT_ID,FILE_ID,RELATIVE_FNO,BLOCK_ID,BLOCKS from dba_extents where segment_name='TEST_HWM' ;
可以看到,对 table TEST_HWM 进行move 后,该 table 所在的 blockid 发生了改变,那么数据的rowid 自然也发生了改变。从上面的结果可以看到,现在 table TEST_HWM 的数据分布在AAAA6J和AAAA6K这2个block中了。但是从这4行数据的row id 的顺序来看,这4行数据在table中的存储顺序并没有发生改变。move 是在 block 之间对于数据的物理 copy。
6、测试move 操作对于table的HWM的位置有什么变化
6.1、使用系统视图 all_objects来创建测试 table my_objects,delete 前 9999 行数据:
create table my_objects tablespace HWM as select * from all_objects;delete from my_objects where rownum<10000;select count(*) from my_objects;set serveroutput onexec show_space(p_segname => 'MY_OBJECTS',p_owner => 'NWPP',p_type => 'TABLE');
这里 HWM =1240 -1 + 1 = 1240,然后对 table MY_OBJECTS 进行 move 操作
6.2、对表进行move操作
alter table MY_OBJECTS move;exec show_space(p_segname => 'MY_OBJECTS',p_owner => 'NWPP',p_type => 'TABLE');
可以看到,table MY_OBJECTS 的 HW M 从1240 移动到 1109,table 的 HWM 降低了!
这个实验对于理解HWM对于性能的影响和通过move去降低HWM大小还是有一定意义的,大家有空也可以自己测试下。
后面会分享更多关于devops和DBA方面内容,感兴趣的朋友可以关注下!!