实验1:Hash分区数据在存储内的分布情况
--建立分区所用的表空间
create tablespace tbs_01 datafile 'e:\oradata\tbs_01.dbf' size 10m;
create tablespace tbs_02 datafile 'e:\oradata\tbs_02.dbf' size 10m;
create tablespace tbs_03 datafile 'e:\oradata\tbs_03.dbf' size 10m;
create tablespace tbs_04 datafile 'e:\oradata\tbs_04.dbf' size 10m;
create tablespace tbs_05 datafile 'e:\oradata\tbs_05.dbf' size 10m;
***********************************************************************************************
--建立简单的hash分区表
create table my_partition_hash(id number,name varchar2(50))
partition by hash (id)(
partition part_p1 tablespace tbs_01,
partition part_p2 tablespace tbs_02,
partition part_p3 tablespace tbs_03);
--编写简单的测试脚本
begin
for i in 1..100000 loop
insert into my_partition_hash values(i,to_char(dbms_random.value(0,10000)));
end loop;
end;
SQL> /
PL/SQL procedure successfully completed
SQL> select rowid,a.* from my_partition_hash a order by 2 ;
ROWID ID NAME
------------------ ---------- --------------------------------------------------
AAAMrkAAHAAAAB0AAA 1 5607.9963723232812917055162399270062766
AAAMrlAAIAAAABsAAA 2 7166.3175997058724951251823900959855342
AAAMrkAAHAAAAB0AAB 3 8883.6657483542526392658394011671541228
AAAMrkAAHAAAAB0AAC 4 25.7829500919726357541729716621438957
AAAMrlAAIAAAABsAAB 5 9878.4159860091792651690969130922953165
AAAMrjAAGAAAAB8AAA 6 3182.3870326603656070442919560524161127
AAAMrkAAHAAAAB0AAD 7 2176.1172773398936635065532220640348386
AAAMrlAAIAAAABsAAC 8 9787.6518800601419256634100054549311031
AAAMrkAAHAAAAB0AAE 9 5504.1835344798785801886644821766611187
AAAMrkAAHAAAAB0AAF 10 234.9149834301178860670353495611486643
AAAMrjAAGAAAAB8AAB 11 3776.3775131739941742406839269564195234
AAAMrkAAHAAAAB0AAG 12 5415.9359823957456135752289322512149714
AAAMrjAAGAAAAB8AAC 13 9729.4778632469533215788064074123759684
AAAMrkAAHAAAAB0AAH 14 4067.7206759497601765262162450283522749
AAAMrkAAHAAAAB0AAI 15 1595.8613978103713988792212875962389326
AAAMrkAAHAAAAB0AAJ 16 1732.0461215748270569860501880217144478
AAAMrkAAHAAAAB0AAK 17 8261.6877721367729538083087378412191926
AAAMrlAAIAAAABsAAD 18 5079.679240707749727697315790426727852
AAAMrkAAHAAAAB0AAL 19 1389.6696472274484299739037883811475907
。。。此处省略很多字
--查看objects 的情况
SQL> SELECT object_name,subobject_name,object_id,object_type FROM USER_OBJECTS WHERE OBJECT_NAME = 'MY_PARTITION_HASH';
OBJECT_NAME SUBOBJECT_NAME OBJECT_ID OBJECT_TYPE
-------------------------------------------------------------------------------- ------------------------------ ---------- -------------------
MY_PARTITION_HASH PART_P1 51939 TABLE PARTITION
MY_PARTITION_HASH PART_P2 51940 TABLE PARTITION
MY_PARTITION_HASH PART_P3 51941 TABLE PARTITION
MY_PARTITION_HASH 51938 TABLE
--查看表空间的情况
SQL> select tablespace_name,file_id,relative_fno from dba_data_files where tablespace_name in ('TBS_01','TBS_02','TBS_03');
TABLESPACE_NAME FILE_ID RELATIVE_FNO
------------------------------ ---------- ------------
TBS_01 6 6
TBS_02 7 7
TBS_03 8 8
--只分析查看my_partition_hash前几行的rowid 情况:
ROWID ID
------------------ ----------
AAAMrkAAHAAAAB0AAA 1
AAAMrlAAIAAAABsAAA 2
AAAMrkAAHAAAAB0AAB 3
AAAMrkAAHAAAAB0AAC 4
AAAMrlAAIAAAABsAAB 5
AAAMrjAAGAAAAB8AAA 6
SQL> select 12*power(64,2)+43*power(64,1)+36 data_object_id from dual;
DATA_OBJECT_ID
--------------
51940
--本实验只分析rowid的前9位就行
64进制 AAAMrj=51939 说明存储在PART_P1 的分区里 AAG=6 =》TBS_01 表空间
AAAMrk=51940 说明存储在PART_P2 的分区里 AAH=7 =》TBS_02 表空间
AAAMrl=51941 说明存储在PART_P3 的分区里 AAI=8 =》TBS_03 表空间
可以看到数据按hash 散列的平均算法分配在3个表空间中;
--具体查看下表空间中到底有多少数据
SQL> select count(*) from MY_PARTITION_HASH partition(part_p1);
COUNT(*)
----------
24945
SQL> select count(*) from MY_PARTITION_HASH partition(part_p2);
COUNT(*)
----------
49846
SQL> select count(*) from MY_PARTITION_HASH partition(part_p3);
COUNT(*)
----------
25209
实验2:考虑Hash的混合分区的建立方式
--注意 hash分区无法删除 但truncate可以:
SQL> alter table MY_PARTITION_HASH drop partition part_p1;
alter table MY_PARTITION_HASH drop partition part_p1
ORA-14255: 未按范围, 组合范围或列表方法对表进行分区
注意:
1 hash分区,执行add partition操作的时候,oracle会自动选择一个分区,并重新分配部分记录到新建的分区,会带来I/O操作;
2 执行altertable 时未指定update indexes字句时:
hash分区的所有数据的local索引和global索引会被置为unuseable 需要重新编译;
而range/list 分区,其local索引和global索引不会受影响;
**************************************************************************************************
--混合的组合分区表的数据分布
create table my_mixcompart_rh(RETPERIOD number(2),POSID number(10))
partition by range(retperiod) subpartition by hash(posid)(
partition part_p1 values less than (10) tablespace tbs_01,
partition part_p2 values less than (20) tablespace tbs_02
(subpartition part_p2_h1 tablespace tbs_01,
subpartition part_p2_h2 tablespace tbs_02),
partition part_p3 values less than (30) tablespace tbs_03
subpartitions 3 store in (tbs_01,tbs_02,tbs_03),
partition part_p4 values less than (40) tablespace tbs_04
(subpartition part_p3_h1 tablespace tbs_01,
subpartition part_p3_h2 tablespace tbs_02,
subpartition part_p3_h3 tablespace tbs_03)
);
--查看表空间分布情况
SQL> SELECT PARTITION_NAME,SUBPARTITION_NAME,TABLESPACE_NAME FROM USER_TAB_SUBPARTITIONS
2 WHERE TABLE_NAME='MY_MIXCOMPART_RH'
3 ;
PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
PART_P1 SYS_SUBP21 TBS_01
PART_P2 PART_P2_H2 TBS_02
PART_P2 PART_P2_H1 TBS_01
PART_P3 SYS_SUBP24 TBS_03
PART_P3 SYS_SUBP23 TBS_02
PART_P3 SYS_SUBP22 TBS_01
PART_P4 PART_P3_H3 TBS_03
PART_P4 PART_P3_H2 TBS_02
PART_P4 PART_P3_H1 TBS_01
1 有上例可以看出 ,未指定的分区,有系统自动生成子分区,系统自动命名。
2 指定子分区的,直接按照子分区所指定的表空间进行存储(但在下面的例子中恰好相反)。
********************************************************************************************************************************
--建立模版分区类的range-hash组合分区表
create table my_part_rh(POSID number(10),RETPERIOD number(2))
partition by range(retperiod) subpartition by hash(posid)
subpartition template(
subpartition h1 tablespace tbs_01,
subpartition h2 tablespace tbs_02,
subpartition h3 tablespace tbs_03)(
partition part_p1 values less than(20) tablespace tbs_01,
partition part_p2 values less than(30) tablespace tbs_02,
partition part_p3 values less than(40) tablespace tbs_03,
partition part_p4 values less than (maxvalue) tablespace tbs_04);
--查看分区表内子分区分布的表空间
SQL> SELECT PARTITION_NAME,SUBPARTITION_NAME,TABLESPACE_NAME FROM USER_TAB_SUBPARTITIONS
2 WHERE TABLE_NAME='MY_PART_RH'
3 ;
PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
PART_P1 PART_P1_H3 TBS_01
PART_P1 PART_P1_H2 TBS_01
PART_P1 PART_P1_H1 TBS_01
PART_P2 PART_P2_H3 TBS_02
PART_P2 PART_P2_H2 TBS_02
PART_P2 PART_P2_H1 TBS_02
PART_P3 PART_P3_H3 TBS_03
PART_P3 PART_P3_H2 TBS_03
PART_P3 PART_P3_H1 TBS_03
PART_P4 PART_P4_H3 TBS_04
PART_P4 PART_P4_H2 TBS_04
PART_P4 PART_P4_H1 TBS_04
以上我们会发现一件很有趣的事情,指定的subpatition的子分区表都会依据主分区的retperiod值存储在相应的表空间中。
很显然在template 分区表的建立中tablespace 选项貌似已经没有用了,继续试验
drop table my_part_rh;--删除表
create table my_part_rh(POSID number(10),RETPERIOD number(2))
partition by range(retperiod) subpartition by hash(posid)
subpartition template(
subpartition h1 ,
subpartition h2 ,
subpartition h3 )(
partition part_p1 values less than(2) tablespace tbs_01,
partition part_p2 values less than(3) tablespace tbs_02,
partition part_p3 values less than(4) tablespace tbs_03,
partition part_p4 values less than (maxvalue) tablespace tbs_04);
成功建立表,支持以上假设。
****************************************************************************************************************************