1. 程式人生 > >oracle分割槽表

oracle分割槽表

oracle分割槽表

分割槽原則:當資料量超過2000W時,可以考慮使用分割槽表
原理:將一張表分成好幾個區域(表空間劃分的磁碟空間)
作用:提高效率

分割槽表儘量建表時建立,
如果是後期優化時建分割槽表,一定要先備份

分割槽型別 型別描述
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'))
);

插入資料

插入資料時,指定分割槽表或者不指定分割槽表都是可以的,
指定分割槽表時,要正確指定,不然會報錯

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列分割槽

新建

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) --喪偶
);

插入資料

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;

檢視未婚的數量

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雜湊分割槽

也叫雜湊分割槽,用的頻率較低,

當資料較大,要建分割槽表時
但是又沒有合適的範圍欄位和列欄位
會將表裡的資料,根據雜湊演算法,相對平均的分配到建立的分割槽中

新建

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

比自己備份再還原效率要高一