oracle分區表

oracle分區表

分區原則:當數據量超過2000W時,能夠考慮使用分區表
原理:將一張表分紅好幾個區域(表空間劃分的磁盤空間)
做用:提升效率算法

分區表儘可能建表時建立,
若是是後期優化時建分區表,必定要先備份oracle

分區類型 類型描述
range: 按照範圍分區,一般是按照時間字段分區,好比申請時間,入職時間
list: 按照分佈分區,好比身份證號碼最後一位
hash: 按照hash值分配分區,相對平均的分配到建立的分區中

range範圍分區

語法

partition by range (字段)
( 
partition 分區名1 values less than (值1或日期1),
partition 分區名2 values less than (值2或日期2),
partition 分區名3 values less than (值3或日期3),...
partition 分區名4 values less than (maxvalue)
);
/*values less than 特色:
values <值1
values>=值1 and values <值2
values>=值2 and values <值3
values>=值3 and values <值4
...*/
關鍵字 描述
partition by 指明是分區表,range肯定分區方式,join_date是分區鍵,必須是表中的一列
partition 後跟分區名字,分區名字必須全庫惟一,不能重複
values less than 即當分區鍵的值小於其後的值時,數據落入本分區
maxvalue 用於最大分區

新建

create table testRANGE
(
v_date date,
v_month varchar2(6),
v_day varchar2(8),
client_no varchar2(4),
fee number
)
partition by range(v_date)
(
  partition p_201712 values less than (to_date('2018/01/01 00:00:00','yyyy/mm/dd HH24:mi:ss')),
  partition p_201801 values less than (to_date('2018/02/01 00:00:00','yyyy/mm/dd HH24:mi:ss')),
  partition p_201802 values less than (to_date('2018/03/01 00:00:00','yyyy/mm/dd HH24:mi:ss')),
  partition p_201803 values less than (to_date('2018/04/01 00:00:00','yyyy/mm/dd HH24:mi:ss'))
);

插入數據

插入數據時,指定分區表或者不指定分區表都是能夠的,
指定分區表時,要正確指定,否則會報錯less

insert into testRANGE
select to_date('20180331','yyyymmdd'),'201803','20180331','0001',80
from dual;
commit
insert into testRANGE partition(p_201803)
select to_date('20180331','yyyymmdd'),'201803','20180331','0001',80
from dual;
commit

查詢三月的數據

SQL> select * from testRANGE partition(p_201803);

V_DATE      V_MONTH V_DAY    CLIENT_NO        FEE
----------- ------- -------- --------- ----------
2018/3/31   201803  20180331 0001              80
2018/3/31   201803  20180331 0001              80
SQL> 
SQL> select * from testRANGE WHERE
  2  V_DATE>=TO_DATE('20180301','YYYY/MM/DD')
  3  AND
  4  V_DATE<TO_DATE('20180401','YYYY/MM/DD')
  5  ;

V_DATE      V_MONTH V_DAY    CLIENT_NO        FEE
----------- ------- -------- --------- ----------
2018/3/31   201803  20180331 0001              80
2018/3/31   201803  20180331 0001              80

添加表分區

表必定是分區表才能新增測試

alter table testRANGE add partition p_201804 values less than (to_date('20180501 00:00:00','YYYYMMDD HH24:MI:SS'));

刪除分區表

alter table testrange drop partition p_201803;

當刪除某一個數據分區時,原先屬於該分區的數據,也會消失
慎重優化

SQL> select * from testRANGE;

V_DATE      V_MONTH V_DAY    CLIENT_NO        FEE
----------- ------- -------- --------- ----------

list列分區

新建code

create table testlist
(
id number(8),
name varchar(50),
gender varchar(1), --性別
m_s varchar(1) --婚姻狀態
)
partition by list (m_s)
(
  partition p_married values ('1'), --已婚
  partition p_unmarried values ('2'), --未婚
  partition p_divorce values ('3'), --離異
  partition p_widowed values (4) --喪偶
);

插入數據hash

insert into testlist
select 1,'tom','1','2' from dual
union all
select 2,'join','2','2' from dual
union all
select 3,'josn','2','3' from dual
union all
select 4,'mon','1','4' from dual;

查看未婚的數量it

SQL> select count(1) from testlist
  2  where m_s='2';

  COUNT(1)
----------
         2

SQL> 
SQL> select count(1) from testlist
  2  partition(p_unmarried);

  COUNT(1)
----------
         2

hash哈希分區

也叫散列分區,用的頻率較低,io

當數據較大,要建分區表時
可是又沒有合適的範圍字段和列字段
會將表裏的數據,根據哈希算法,相對平均的分配到建立的分區中table

新建

create table testhash
(
id varchar(10),
name varchar(100)
)
partition by hash (id)
(
partition aa,
partition bb,
partition cc
);

插入數據

insert into testhash
select '1','name1' from dual
union all
select '2','name2' from dual
union all
select '3','name3' from dual
union all
select '4','name4' from dual
union all
select '5','name5' from dual
union all
select '6','name6' from dual;

查看數據在三個分區表的分佈狀況

SQL> select * from testhash partition(aa);

ID         NAME
----- -------
2          name2
4          name4

SQL> select * from testhash partition(bb);

ID         NAME
----- -------
1          name1
3          name3
5          name5
6          name6

SQL> select * from testhash partition(cc);

ID         NAME
----- -------

複合分區

將上面的三大分區,兩兩組合
在使用中一般將範圍分區做爲主分區

新建

create table testemp
(
v_empno varchar2(10),
v_name varchar2(100),
v_date date,
v_deptno varchar2(3)
)
partition by range (v_date) subpartition by list (v_deptno)
(
partition p_201712 values less than
(to_date('2018/01/01 00:00:00','yyyy/mm/dd hh24:mi:ss'))
(subpartition a1 values('10'),
subpartition a2 values('20'),
subpartition a3 values('30'),
subpartition a4 values('40')),

partition p_201801 values less than
(to_date('2018/02/01 00:00:00','yyyy/mm/dd hh24:mi:ss'))
(subpartition b1 values('10'),
subpartition b2 values('20'),
subpartition b3 values('30'),
subpartition b4 values('40'))
);

插入數據

insert into testemp
select '001','name1',to_date('20180102','yyyymmdd'),10 from dual
union all
select '002','name2',to_date('20171027','yyyymmdd'),10 from dual;

查看主分區

SQL> select * from testemp partition(p_201712);

V_EMPNO    V_NAME      V_DATE      V_DEPTNO
-------- -------- ----------- --------
002        name2       2017/10/27  10

查看子分區

SQL> select * from testemp subpartition(b1);

V_EMPNO    V_NAME      V_DATE      V_DEPTNO
-------- ------- ----------- --------
001        name1     2018/1/2    10

自增分區

新建

create table testzz
(
stat_id varchar2(10),
stat_date date
)
partition by range (stat_date)
interval (numtoyminterval (1,'month'))
(
partition p1 values less than
(to_date('2018/02/01 00:00:00','yyyy/mm/dd hh24:mi:ss'))
);

month處也可改成year

插入數據

其中兩條數據不符合分區狀況

insert into testzz
select '1',to_date('20180118','yyyymmdd') from dual
union all
select '2',to_date('20180218','yyyymmdd') from dual
union all
select '3',to_date('20180318','yyyymmdd') from dual;

查看錶結構時,發現多了兩個表結構

partition SYS_P21 values less than (TO_DATE(' 2018-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
partition SYS_P22 values less than (TO_DATE(' 2018-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))

交換分區

用上面的表testzz分區p1來測試

SQL> select * from testzz partition(p1);

STAT_ID    STAT_DATE
---------- -----------
1          2018/1/18

建立一個和testzz表結構相同的表,並建立數據

SQL> create table testswap as
  2  select * from testzz where 1=2;

Table created
insert into testswap
select '0001',to_date('20180101','yyyymmdd') from dual
union all
select '0002',to_date('20180103','yyyymmdd') from dual
union all
select '0003',to_date('20180104','yyyymmdd') from dual;
SQL> select * from testswap;

STAT_ID    STAT_DATE
---------- -----------
0001       2018/1/1
0002       2018/1/3
0003       2018/1/4

將分區表testzz的p1分區和普通表testswap進行交換
注意:這裏的testswap表中的時間是符合p1分區的規則的

SQL> alter table testzz
  2  exchange partition p1
  3  with table testswap;

Table altered

再次查看

SQL> select * from testswap;

STAT_ID    STAT_DATE
---------- -----------
1          2018/1/18

SQL> select * from testzz partition(p1);

STAT_ID    STAT_DATE
---------- -----------
0001       2018/1/1
0002       2018/1/3
0003       2018/1/4

比本身備份再還原效率要高一點

相關文章
相關標籤/搜索