oracle分区表
_冥想 人气:2oracle分区表
分区原则:当数据量超过2000W时,可以考虑使用分区表
原理:将一张表分成好几个区域(表空间划分的磁盘空间)
作用:提高效率
分区表尽量建表时创建,
如果是后期优化时建分区表,一定要先备份
分区类型 | 类型描述 |
---|---|
range: | 按照范围分区,通常是按照时间字段分区,比如申请时间,入职时间 |
list: | 按照分布分区,比如SFZ号码最后一位 |
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/mmhttps://img.qb5200.com/download-x/dd HH24:mi:ss')),
partition p_201801 values less than (to_date('2018/02/01 00:00:00','yyyy/mmhttps://img.qb5200.com/download-x/dd HH24:mi:ss')),
partition p_201802 values less than (to_date('2018/03/01 00:00:00','yyyy/mmhttps://img.qb5200.com/download-x/dd HH24:mi:ss')),
partition p_201803 values less than (to_date('2018/04/01 00:00:00','yyyy/mmhttps://img.qb5200.com/download-x/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/mmhttps://img.qb5200.com/download-x/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/mmhttps://img.qb5200.com/download-x/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/mmhttps://img.qb5200.com/download-x/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
比自己备份再还原效率要高一点
加载全部内容