关于Hash分区的思考

来源:互联网 发布:麻将教程新手入门软件 编辑:程序博客网 时间:2024/05/22 11:42

实验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);

成功建立表,支持以上假设。

****************************************************************************************************************************

原创粉丝点击