為什么要創建oracle分區表?
一般情況下,如果不分區,則每次查詢的對象都是一整張表,如果采用了表分區,那么可以根據具體的分區字段當作條件來避免掃描整張表,減少IO的掃描以提高表的查詢速度。
新建(按照日期自動分區)分區表
SQL> create table test_partion( 2 pk_id number(38) generated as identity (start with 1 increment by 1), 3 P_day date, 4 words varchar2(200), 5 constraint pk_test_partition_id primary key (pk_id) 6 ) 7 partition by range(P_day) 8 interval (numtodsinterval(1,'day')) 9 ( 10 partition part_20170622 values less than (to_date('20170622','yyyyMMdd')) 11 ); Table created
- 嘗試插入數據,之后查看動態分區表的分區個數:
SQL> select * from test_partion ; PK_ID P_DAY WORDS --------------------------------------- ----------- ------
SQL> insert into test_partion (p_day,words) values (to_date('20170622','yyyyMMdd'),'00001'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170623','yyyyMMdd'),'00002'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170623','yyyyMMdd'),'00003'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170624','yyyyMMdd'),'00004'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170623','yyyyMMdd'),'00005'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170625','yyyyMMdd'),'00006'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170626','yyyyMMdd'),'00006'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170627','yyyyMMdd'),'00006'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170628','yyyyMMdd'),'00006'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170629','yyyyMMdd'),'00006'); 1 row inserted
SQL> select table_name,partition_name,high_value from user_tab_partitions where table_name='TEST_PARTION'; TABLE_NAME PARTITION_NAME HIGH_VALUE --------------- ---------------- -------------------------------------------------------------------------------- TEST_PARTION PART_20170622 TO_DATE(' 2017-06-22 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2252 TO_DATE(' 2017-06-23 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2253 TO_DATE(' 2017-06-24 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2254 TO_DATE(' 2017-06-25 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2255 TO_DATE(' 2017-06-26 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2256 TO_DATE(' 2017-06-27 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2257 TO_DATE(' 2017-06-28 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2258 TO_DATE(' 2017-06-29 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2259 TO_DATE(' 2017-06-30 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA 9 rows selected
從上邊表中我們基本可以看出,除了分區PART_20170622是我們動態創建的分區外,其他SYS_*分區都是動態創建的。
接下來查看每個分區表的數據分區情況:
SQL> select * from test_partion partition(PART_20170622); PK_ID P_DAY WORDS --------------------------------------- ----------- -------- SQL> select * from test_partion partition(SYS_P2252); PK_ID P_DAY WORDS --------------------------------------- ----------- -------- 1 2017/6/22 00001 SQL> select * from test_partion partition(SYS_P2253); PK_ID P_DAY WORDS --------------------------------------- ----------- -------- 2 2017/6/23 00002 3 2017/6/23 00003 5 2017/6/23 00005 SQL> select * from test_partion partition(SYS_P2254); PK_ID P_DAY WORDS --------------------------------------- ----------- ------- 4 2017/6/24 00004 SQL> select * from test_partion partition(SYS_P2255); PK_ID P_DAY WORDS --------------------------------------- ----------- ------- 6 2017/6/25 00006 SQL> select * from test_partion partition(SYS_P2256); PK_ID P_DAY WORDS --------------------------------------- ----------- ------- 7 2017/6/26 00006 SQL> select * from test_partion partition(SYS_P2257); PK_ID P_DAY WORDS --------------------------------------- ----------- ------- 8 2017/6/27 00006 SQL> select * from test_partion partition(SYS_P2258); PK_ID P_DAY WORDS --------------------------------------- ----------- ------- 9 2017/6/28 00006 SQL> select * from test_partion partition(SYS_P2259); PK_ID P_DAY WORDS --------------------------------------- ----------- ------ 10 2017/6/29 00006
分區操作:
1)刪除某個分區表中的數據
SQL> delete from test_partion partition(SYS_P2259); 1 row deleted SQL> select * from test_partion partition(SYS_P2259); PK_ID P_DAY WORDS --------------------------------------- ----------- ------
2)刪除某個分區
SQL> alter table test_partion drop partition SYS_P2259; Table altered
刪除分區之后,查看表分區情況。
SQL> select table_name,partition_name,high_value from user_tab_partitions where table_name='TEST_PARTION'; TABLE_NAME PARTITION_NAME HIGH_VALUE --------------- ---------------- -------------------------------------------------------------------------------- TEST_PARTION PART_20170622 TO_DATE(' 2017-06-22 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2252 TO_DATE(' 2017-06-23 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2253 TO_DATE(' 2017-06-24 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2254 TO_DATE(' 2017-06-25 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2255 TO_DATE(' 2017-06-26 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2256 TO_DATE(' 2017-06-27 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2257 TO_DATE(' 2017-06-28 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2258 TO_DATE(' 2017-06-29 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA 8 rows selected
注:drop partition時,該分區內存儲的數據也將同時刪除,你的本意是希望刪除掉指定的分區但保留數據,你應該使用merge partition,執行該語句會導致glocal索引的失效需要重建全局索引
3)合並分區
相鄰的分區可以通過命令merge partition合並為一個分區,同時分區中的數據也將會被合並到同一個分區中。
新分區的下邊界為原來邊界值較低的分區,上邊界為原來邊界值較高的分區,原先的局部索引相應也會合並,全局索引會失效,需要rebuild。
參考:http://www.cnblogs.com/wangfg/p/5286519.html
SQL> alter table test_partion merge partitions SYS_P2253,SYS_P2254 into partition SYS_P2253_to_P2254; Table altered SQL> select table_name,partition_name,high_value from user_tab_partitions where table_name='TEST_PARTION'; TABLE_NAME PARTITION_NAME HIGH_VALUE -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- TEST_PARTION PART_20170622 TO_DATE(' 2017-06-22 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2252 TO_DATE(' 2017-06-23 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2253_TO_P2254 TO_DATE(' 2017-06-25 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2255 TO_DATE(' 2017-06-26 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2256 TO_DATE(' 2017-06-27 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2257 TO_DATE(' 2017-06-28 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2258 TO_DATE(' 2017-06-29 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA 7 rows selected SQL> select * from test_partion partition(SYS_P2253_TO_P2254); PK_ID P_DAY WORDS --------------------------------------- ----------- -------------------------------------------------------------------------------- 2 2017/6/23 00002 3 2017/6/23 00003 5 2017/6/23 00005 4 2017/6/24 00004 SQL> insert into test_partion (p_day,words) values (to_date('20170623','yyyyMMdd'),'06665'); insert into test_partion (p_day,words) values (to_date('20170623','yyyyMMdd'),'06665') ORA-01502: 索引 "NETPLAN_ONLINE_APPUSER.PK_TEST_PARTITION_ID" 或這類索引的分區處於不可用狀態 SQL> alter index PK_TEST_PARTITION_ID rebuild; Index altered SQL> insert into test_partion (p_day,words) values (to_date('20170623','yyyyMMdd'),'06665'); 1 row inserted SQL> insert into test_partion (p_day,words) values (to_date('20170624','yyyyMMdd'),'06665'); 1 row inserted SQL> select * from test_partion partition(SYS_P2253_TO_P2254); PK_ID P_DAY WORDS --------------------------------------- ----------- -------------------------------------------------------------------------------- 2 2017/6/23 00002 3 2017/6/23 00003 5 2017/6/23 00005 4 2017/6/24 00004 12 2017/6/23 06665 13 2017/6/24 06665 6 rows selected
4)分區重命名
SQL> SQL> alter table test_partion rename partition SYS_P2253_to_P2254 TO SYS_P2253_to_P2254___; Table altered SQL> insert into test_partion (p_day,words) values (to_date('20170624','yyyyMMdd'),'76665'); 1 row inserted SQL> select table_name,partition_name,high_value from user_tab_partitions where table_name='TEST_PARTION'; TABLE_NAME PARTITION_NAME HIGH_VALUE -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- TEST_PARTION PART_20170622 TO_DATE(' 2017-06-22 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2252 TO_DATE(' 2017-06-23 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2253_TO_P2254___ TO_DATE(' 2017-06-25 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2255 TO_DATE(' 2017-06-26 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2256 TO_DATE(' 2017-06-27 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2257 TO_DATE(' 2017-06-28 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST_PARTION SYS_P2258 TO_DATE(' 2017-06-29 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA 7 rows selected SQL> insert into test_partion (p_day,words) values (to_date('20170624','yyyyMMdd'),'76665'); 1 row inserted SQL> select * from test_partion partition(SYS_P2253_TO_P2254___); PK_ID P_DAY WORDS --------------------------------------- ----------- -------------------------------------------------------------------------------- 2 2017/6/23 00002 3 2017/6/23 00003 5 2017/6/23 00005 4 2017/6/24 00004 12 2017/6/23 06665 13 2017/6/24 06665 14 2017/6/24 76665 15 2017/6/24 76665 8 rows selected
因為這里是動態分區,所以就不介紹怎么添加分區。