Detailed Oracle table partitioning (partition table)

1 Overview

1. 目的:提高大表的查询效率

2. 概念:将一个表划分为多个分区表,"分而治之"

3. 优缺点
   优点:
   (1) '改善查询性能': 分区对象的查询仅搜索自己关系的分区
   (2) '增强可用性'  : 如果某个分区出现故障,其它分区的数据仍然可用
   (3) '维护方便'    : 如果某个分区出现故障,仅修复该分区即可
   (4) '均衡I/O'     : 将不同的分区放置不同的磁盘,以均衡 I/O,改善整个系统性能

   缺点:
   (1) 已经存在的表无法直接转化为分区表 -- 不过有很多间接方法,如:重定义表

4. 适用情况
   (1) 表的大小超过 2GB

1.1 Mind Map

Insert picture description here

2 categories

2.1 Traditional table partition

2.1.1 range partition

Case 1: Value range partition

create table pt_range_test1(
  pid   number(10),
  pname varchar2(30)
) partition by range(pid)(
  partition p1 values less than(1000) tablespace tetstbs1,
  partition p2 values less than(2000) tablespace tetstbs2,
  partition p3 values less than(maxvalue) tablespace tetstbs3
) enable row movement;

Insert data:

insert into pt_range_test1 (pid, pname) values (1, '瑶瑶');
insert into pt_range_test1 (pid, pname) values (1500, '倩倩');
insert into pt_range_test1 (pid, pname) values (null, '优优');
commit;

Query data:

select * from user_tab_partitions t;

select 'P1' 分区名, t.* from pt_range_test1 partition (p1) t union all
select 'P2' 分区名, t.* from pt_range_test1 partition (p2) t union all
select 'P3' 分区名, t.* from pt_range_test1 partition (p3) t

Insert picture description here

Case 2: Time range partition (similarly)

create table pt_range_test2(
  pid         number(10),
  pname       varchar2(30),
  create_date date
) partition by range(create_date)(
  partition p1 values less than(to_date('2020-01-01', 'YYYY-MM-DD')) tablespace tetstbs1,
  partition p2 values less than(to_date('2021-01-01', 'YYYY-MM-DD')) tablespace tetstbs2,
  partition p3 values less than(maxvalue) tablespace tetstbs3
) enable row movement;

2.1.2 List partition list

create table pt_list_test(
  pid   number(10),
  pname varchar2(30),
  sex   varchar2(10)
) partition by list(sex)(
  partition p1 values ('MAN', '男') tablespace tetstbs1,
  partition p2 values ('WOMAN', '女') tablespace tetstbs2,
  partition p3 values (default) tablespace tetstbs3
) enable row movement;

Insert data:

insert into pt_list_test (pid, pname, sex) values (1, '瑶瑶', '男');
insert into pt_list_test (pid, pname, sex) values (2, '倩倩', 'WOMAN');
insert into pt_list_test (pid, pname, sex) values (3, '优优', 'GOD');
commit;

Query data:

select 'P1' 分区名, t.* from pt_list_test partition (p1) t union all
select 'P2' 分区名, t.* from pt_list_test partition (p2) t union all
select 'P3' 分区名, t.* from pt_list_test partition (p3) t

Insert picture description here

2.1.3 Hash partition hash

create table pt_hash_test(
  pid   number(10),
  pname varchar2(30)
) partition by hash(pid)(
  partition p1 tablespace tetstbs1,
  partition p2 tablespace tetstbs2,
  partition p3 tablespace tetstbs3,
  partition p4 tablespace tetstbs4,
);

Shorthand:

create table pt_hash_test2(
  pid   number(10),
  pname varchar2(30)
) partition by hash(pid) 
  partitions 4 store in (tetstbs1, tetstbs2, tetstbs3, tetstbs4);

2.1.4 Compound partition range + list or hash

Case 1: range + list

create table pt_range_list_test(
   pid         number(10),
   pname       varchar2(30),
   sex         varchar2(10),
   create_date date
) partition by range(create_date) 
  subpartition by list(sex)(
    partition p1 values less than(to_date('2020-01-01', 'YYYY-MM-DD')) tablespace tetstbs1(
      subpartition sub1p1 values('MAN') tablespace tetstbs1,
      subpartition sub2p1 values('WOMAN') tablespace tetstbs1,
      subpartition sub3p1 values(default) tablespace tetstbs1
    ),
    partition p2 values less than(to_date('2021-01-01', 'YYYY-MM-DD')) tablespace tetstbs2(
      subpartition sub1p2 values('MAN') tablespace tetstbs2,
      subpartition sub2p2 values('WOMAN') tablespace tetstbs2,
      subpartition sub3p2 values(default) tablespace tetstbs2
    ),
    partition p3 values less than(maxvalue) tablespace tetstbs3(
      subpartition sub1p3 values('MAN') tablespace tetstbs3,
      subpartition sub2p3 values('WOMAN') tablespace tetstbs3,
      subpartition sub3p3 values(default) tablespace tetstbs3
    )
  ) enable row movement;

Case 1: range + hash

create table pt_range_hash_test(
   pid         number(10),
   pname       varchar2(30),
   sex         varchar2(10),
   create_date date
) partition by range(create_date) 
  subpartition by hash(pid) subpartitions 4 store in (tetstbs1, tetstbs2, tetstbs3, tetstbs4)(
     partition p1 values less than(to_date('2020-01-01', 'YYYY-MM-DD')) tablespace tetstbs1,
     partition p2 values less than(to_date('2021-01-01', 'YYYY-MM-DD')) tablespace tetstbs2,
     partition p3 values less than(to_date('2022-01-01', 'YYYY-MM-DD')) tablespace tetstbs3,
     partition p4 values less than(maxvalue) tablespace tetstbs4
  ) enable row movement;

2.2 11g new feature partition

2.1.1 Reference partition reference

  • The foreign key column must not be null
-- 父表
create table pt_reference_father_test(
   pid         number(10),
   pname       varchar2(30),
   create_date date,
   constraint pk_ptrft_pid primary key(pid)
) partition by range(create_date)(
    partition p1 values less than(to_date('2020-01-01', 'YYYY-MM-DD')) tablespace tetstbs1,
    partition p2 values less than(to_date('2021-01-01', 'YYYY-MM-DD')) tablespace tetstbs2,
    partition p3 values less than(maxvalue) tablespace tetstbs3
  ) enable row movement;


-- 子表
create table pt_reference_son_test(
   pid     number(10) not null, -- 必须 not null,否则报错
   item_id number(10),
   constraint pk_ptrst_item_id primary key(item_id),
   constraint fk_ptrst_pid foreign key(pid)
   references pt_reference_father_test(pid)       
) partition by reference(fk_ptrst_pid)
  enable row movement;

2.1.2 interval partition

  • There must be an initial partition and cannot be deleted (unless the table is deleted directly)
-- 初始时间范围分区 2020-01-01
-- 之后数据每间隔 1 年,新建一个分区
create table pt_interval_test(
  pid         number(10),
  pname       varchar2(30),
  create_date date
) partition by range(create_date) 
  interval(numtoyminterval(1, 'YEAR'))(
     partition p1 values less than(to_date('2020-01-01', 'YYYY-MM-DD')) tablespace tetstbs1
  );

Insert data separately and observe the changes:

insert into pt_interval_test(pid, pname, create_date) values(1, '瑶瑶', to_date('2019-01-01', 'YYYY-MM-DD'));

insert into pt_interval_test(pid, pname, create_date) values(2, '倩倩', to_date('2020-01-01', 'YYYY-MM-DD'));

select * from user_tab_partitions t where t.table_name = upper('pt_interval_test');

Insert picture description here

2.1.3 Virtual column partition virtual

  • Establish a partition on a virtual column ( calculation result of a function or expression )
create table pt_virtual_test(
  pid         number(10),
  pname       varchar2(30),
  create_date date,
  create_quarterly as (to_char(create_date,'D')) virtual
) partition by list(create_quarterly)(
    partition p1 values(1) tablespace tetstbs1,
    partition p2 values(2) tablespace tetstbs2,
    partition p3 values(3) tablespace tetstbs3,
    partition p4 values(4) tablespace tetstbs4,
    partition p5 values(default) tablespace tetstbs4
  );

2.1.4 System partition system

  • Cannot specify partition column
create table pt_system_test(
  pid   number(10),
  pname varchar2(30)
) partition by system(
    partition p1 tablespace tetstbs1,
    partition p2 tablespace tetstbs2,
    partition p3 tablespace tetstbs3
  );

3 Management

3.1 Table partition

1. 查询: 
   (1) select * from user_tab_partitions t;

2. 添加: 
   (1) alter table <table_name> add partition <partition_name> values less than(to_date('2020-02-02', 'YYYY-MM-DD'));
   (2) alter table <table_name> add partition <partition_name> values less than(1000);

3. 删除: (请注意:无法删除分区表唯一的分区,除非删除表)
   (1) alter table <table_name> drop partition <partition_name>;
   (2) alter table <table_name> drop subpartition <subpartition_name>;

4. 截断分区('清空某个分区的数据'(1) alter table <table_name> truncate partition <partition_name>;
   (2) alter table <table_name> truncate subpartition <subpartition_name>;

5. 拆分分区('拆分后,原来分区不再存在'(1) alter table <table_name> sblit partition <p12> at(to_date('2020-01-01', 'YYYY-MM-DD')) into (partition p1, partition p2);
   
6. 合并分区
   (1) alter table <table_name> merge partitions <p1>, <p2> into partition <p12>;

7. 重命名分区
   (1) alter table <table_name> rename partition <pold> to <pnew>

3.2 Table space

1. 查询
   (1) select * from user_tablespaces t;
   
2. 创建 -- 创建表空间时,可选项有很多,此处仅列出必选项
   create tablespace "tbs"
   datafile 'D:\oracle\tbs_01.dbf'
   size 10m;

3. 删除
   (1) 仅删除表空间:drop tablespace tbs;
   (2) 删除表空间和数据文件:drop tablespace tbs including contents and datafiles;

Guess you like

Origin blog.csdn.net/qq_34745941/article/details/109027781