1.建立普通表oracle
create table normal_shp(id number,day date,city_number number,note varchar2(100)) tablespace p;less
插入10000條記錄dom
insert into normal_shp(id,day,city_number,note) select rownum,to_date(to_char(sysdate-180,'J')+trunc(dbms_random.value(0,180)),'J'),ceil(dbms_random.value(1,7)),rpad('a',100,'a') from dual connect by rownum <=100000;性能
2.建立範圍分區表spa
create table range_shp(id number,day date,city_number number,note varchar2(100))orm
partition by range(day)blog
(遞歸
partition p1 values less than (to_date('2019-02-01','YYYY-MM-DD')) tablespace p1,索引
partition p2 values less than (to_date('2019-03-01','YYYY-MM-DD')) tablespace p2,ci
partition p3 values less than (to_date('2019-04-01','YYYY-MM-DD')) tablespace p3,
partition p4 values less than (to_date('2019-05-01','YYYY-MM-DD')) tablespace p4,
partition p5 values less than (to_date('2019-06-01','YYYY-MM-DD')) tablespace p5,
partition p6 values less than (to_date('2019-07-01','YYYY-MM-DD')) tablespace p6,
partition p_max values less than (maxvalue) tablespace p
)
;
插入100000條記錄
insert into range_shp(id,day,city_number,note)
select rownum,to_date(to_char(sysdate-180,'J')+trunc(dbms_random.value(0,180)),'J'),
ceil(dbms_random.value(1,7)),
rpad('a',100,'a')
from dual
connect by rownum <=100000;
3.性能對比
select * from normal_shp; --普通表
select * from range_shp; --範圍分區表
普通表 |
範圍分區表 |
![]() |
|
在不加任何條件時,進行查詢發現,二者的邏輯讀數量大體相同,花費大體相同;其中範圍分區表的邏輯讀和花費甚至略高於範圍分區表。這是由於分區數量較多,oracle須要管理的段更多(見下圖),在進行操做時會引起大量內部的遞歸調用(recursive calls),於是小表不建議建分區。
對指定時間進行查詢:
select * from normal_shp where day=to_date(‘2019-04-01’,’YYYY-MM-DD’);
select * from range_shp where day=to_date(‘2019-04-01’,’YYYY-MM-DD’);
普通表 |
範圍分區表 |
![]() |
![]() |
由上圖可知,在對指定時間作查詢時,對時間作範圍分區表的查詢更加高效,邏輯讀從1853降到了341,花費也更加低。由執行計劃仔細觀察得,pstart和pstop均爲4,表明範圍分區表進行查詢時,只對於第4個分區進行了全表掃描。
4.建立列表分區表
create table list_shp(id number,day date,city_number number,note varchar2(100))
partition by list(city_number)
(
partition p1 values (1) tablespace p1,
partition p2 values (2) tablespace p2,
partition p3 values (3) tablespace p3,
partition p4 values (4) tablespace p4,
partition p5 values (5) tablespace p5,
partition p6 values (6) tablespace p6,
partition p_other values (default) tablespace p
)
;
5.建立hash分區表
create table hash_shp(id number,day date,city_number number,note varchar2(100))
partition by hash(day)
partitions 6
store in (p1,p2,p3,p4,p5,p6)
;
注:若是表空間數量大於分區數量,則會採用前幾個;若是表空間數量小於分區數量,表空間按序循環使用。散列分區的個數儘可能使用偶數個。
或者:
-- Create table
create table SYS.HASH_SHP
(
id NUMBER,
day DATE,
city_number NUMBER,
note VARCHAR2(100)
)
partition by hash (DAY)
(
partition SYS_P41 tablespace P1,
partition SYS_P42 tablespace P2,
partition SYS_P43 tablespace P3,
partition SYS_P44 tablespace P4,
partition SYS_P45 tablespace P5,
partition SYS_P46 tablespace P6
);
6.建立組合分區表
經常使用的:範圍-列表分區
create table range_list_shp(id number,day date,city_number number,note varchar2(100))
partition by range(day)
subpartition by list(city_number)
subpartition template
(
subpartition p1 values (1) tablespace p1,
subpartition p2 values (2) tablespace p2,
subpartition p3 values (3) tablespace p3,
subpartition p4 values (4) tablespace p4,
subpartition p5 values (5) tablespace p5,
subpartition p6 values (6) tablespace p6,
subpartition p_other values (default) tablespace p)
(
partition p1 values less than (to_date('2019-02-01','YYYY-MM-DD')) tablespace p1,
partition p2 values less than (to_date('2019-03-01','YYYY-MM-DD')) tablespace p2,
partition p3 values less than (to_date('2019-04-01','YYYY-MM-DD')) tablespace p3,
partition p4 values less than (to_date('2019-05-01','YYYY-MM-DD')) tablespace p4,
partition p5 values less than (to_date('2019-06-01','YYYY-MM-DD')) tablespace p5,
partition p6 values less than (to_date('2019-07-01','YYYY-MM-DD')) tablespace p6,
partition p_max values less than (maxvalue) tablespace p
)
;
7.分區數據交換
分區表的某個分區與普通表進行分區數據交換
alter table range_shp exchange partition p1 with table normal_shp1;
alter table range_list_shp subpartition p1_p1 with table normal_shp1;
(普通表的表結構要和分區一致)
8.分區表的管理
(1)清理分區
alter table range_shp truncate partition p1;
alter table range_list_shp truncate subpartition p1_p1;
(2) 增長表分區
當分區表存在默認條件分區,range中的maxvalue分區,list分區表中的default分區:
① 先刪除原默認分區,增長分區後再添加默認分區
alter table range_shp drop partition p_max; --刪除maxvalue分區
alter table range_shp add partition p_7 values less than (to_date('2019-08-01','YYYY-MM-DD')) tablespace p7; --增長分區
alter table range_shp add partition p_max values less than (maxvalue) tablespace p; --增長maxvalue分區
尤爲注意,刪除默認分區會將數據一併刪除,不會分佈到其餘分區!!!
② 使用拆分分區split的方式進行增長
在目標分區拆分後,被拆分的分區會按照拆分規則將數據從新分佈
alter table list_shp split partition p_other values(7) into (partition p_7 tablespace p7,partition p_other);
alter table range_shp split partition p_max at(to_date('2019-08-01','YYYY-MM-DD')) into (partition p_7 tablespace p6,partition p_other);
對於不存在默認條件分區的分區表,直接增長便可;
(3)合併表分區
對於列表分區,合併的分區無要求;
對於範圍分區,合併的分區需相鄰;
對於散列分區,沒法合併
語法:alter table range_shp merge partitions p1,p2 into partition p0;
(4)收縮分區
只能在散列分區或者組合分區的hash子分區上進行使用
alter table hash_shp coalesce partition;
9.分區表索引的維護
全局索引:create index index1 on list_shp(day);
局部索引:create index index2 on range_shp(day) local;
N/A表示局部索引
截斷一個分區會將全局索引失效,而局部索引不會失效
加參數能夠避免全局索引失效:update global indexes;
Alter table range_shp truncate p1 update global indexes;