分區經過讓您將它們分解爲更小且更易於管理的分區(稱爲分區)來解決支持很是大的表和索引的關鍵問題。不須要修改SQL查詢和DML語句以訪問分區表。可是,在定義分區以後,DDL語句能夠訪問和操做個別分區,而不是整個表或索引。這就是分區能夠簡化大型數據庫對象的可管理性的方式。此外,分區對應用程序徹底透明併發
其它類型的表設計能夠看博客:https://smilenicky.blog.csdn.net/article/details/90315980
普通表和分區表區別,分區表分紅幾部分就有幾個segment,RANGE_PART_TAB是一個分區表oracle
select segment_name, partition_name, segment_type, bytes / 1024 / 1024 "字節數(M)", tablespace_name from user_segments where segment_name IN ('RANGE_PART_TAB', 'NOR_TAB');
引用Oracle官方文檔的說法,https://docs.oracle.com/cd/B19306_01/server.102/b14220/partconc.htm#sthref2604:less
(1) 分區支持數據管理操做,例如數據加載,索引建立和重建,以及分區級別的備份/恢復,而不是整個表。這致使這些操做的時間顯着減小。
(2)分區可提升查詢性能。在許多狀況下,查詢的結果能夠經過訪問分區的子集而不是整個表來實現。對於某些查詢,此技術(稱爲分區 修剪)能夠提供性能的數量級增益。
(3)分區能夠顯着減小計劃停機對維護操做的影響。
(4)分區維護操做的分區獨立性容許您在同一個表或索引的不一樣分區上執行併發維護操做。您還能夠SELECT對不受維護操做影響的分區運行併發和DML操做。
(5)若是將關鍵表和索引劃分爲多個分區以減小維護窗口,恢復時間和故障影響,則分區可提升任務關鍵型數據庫的可用性。
(6)無需對應用程序進行任何修改便可實現分區。例如,您能夠將非分區錶轉換爲分區表,而無需修改SELECT訪問該表的任何語句或DML語句。您無需重寫應用程序代碼便可利用分區。dom
分區類型:分區分爲範圍分區、列表分區、HASH分區、組合分區四種,圖來自Oracle官方網站
性能
關鍵字partition by range網站
create table range_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by range (deal_date) ( partition p1 values less than (TO_DATE('2018-11-01','YYYY-MM-DD')), partition p2 values less than (TO_DATE('2018-12-02','YYYY-MM-DD')), partition p3 values less than (TO_DATE('2019-01-01','YYYY-MM-DD')), partition p4 values less than (TO_DATE('2019-02-01','YYYY-MM-DD')), partition p5 values less than (TO_DATE('2019-03-01','YYYY-MM-DD')), partition p6 values less than (TO_DATE('2019-04-01','YYYY-MM-DD')), partition p7 values less than (TO_DATE('2019-05-01','YYYY-MM-DD')), partition p8 values less than (TO_DATE('2019-06-01','YYYY-MM-DD')), partition p9 values less than (TO_DATE('2019-07-01','YYYY-MM-DD')), partition p10 values less than (TO_DATE('2019-08-01','YYYY-MM-DD')) ); insert into range_part_tab (seq, deal_date, unit_code, remark) select rownum, to_date(to_char(sysdate-365, 'J') + trunc(DBMS_RANDOM.value(0, 365)),'J'), ceil(dbms_random.value(210,220)), rpad('*', 1, '*') from dual connect by rownum <= 1000;
create table list_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by list (unit_code) ( partition p1 values (211), partition p2 values (212), partition p3 values (213), partition p4 values (214), partition p5 values (215), partition p6 values (216), partition p7 values (217), partition p8 values (218), partition p9 values (219), partition p10 values (220), partition p0 values (DEFAULT) ); insert into list_part_tab (seq, deal_date, unit_code, remark) select rownum, to_date(to_char(sysdate-365, 'J') + trunc(DBMS_RANDOM.value(0, 365)),'J'), ceil(dbms_random.value(210,220)), rpad('*', 1, '*') from dual connect by rownum <= 1000; commit;
散列分區也叫hash分區,partitions後接分區數,儘可能設置爲偶數,spa
create table hash_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by hash (deal_date) partitions 12; insert into hash_part_tab (seq, deal_date, unit_code, remark) select rownum, to_date(to_char(sysdate-365, 'J') + trunc(DBMS_RANDOM.value(0, 365)),'J'), ceil(dbms_random.value(210,220)), rpad('*', 1, '*') from dual connect by rownum <= 1000; commit;
組合分區又稱複合分區,主要有兩種:oracle11以前只支持範圍列表分區(RANGE-LIST)和範圍散列分區(RANGE-HASH),oracle11以後支持(範圍範圍分區)RANGE-RANGE、 (列表範圍分區)LIST-RANGE、(列表散列分區)LIST-HASH、(列表列表分區)LIST-LIST這幾種組合,爲了不每一個主分區中都寫相同的從分區,能夠用模板方式(subpartition template).net
圖來自Oracle官方網站:
設計
create table range_list_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by range (deal_date) subpartition by list (unit_code) subpartition template (subpartition s1 values (211), subpartition s2 values (212), subpartition s3 values (213), subpartition s4 values (214), subpartition s5 values (215), subpartition s6 values (216), subpartition s7 values (217), subpartition s8 values (218), subpartition s9 values (219), subpartition s10 values (220), subpartition s0 values (DEFAULT) ) ( partition p1 values less than (TO_DATE('2018-11-01','YYYY-MM-DD')), partition p2 values less than (TO_DATE('2018-12-02','YYYY-MM-DD')), partition p3 values less than (TO_DATE('2019-01-01','YYYY-MM-DD')), partition p4 values less than (TO_DATE('2019-02-01','YYYY-MM-DD')), partition p5 values less than (TO_DATE('2019-03-01','YYYY-MM-DD')), partition p6 values less than (TO_DATE('2019-04-01','YYYY-MM-DD')), partition p7 values less than (TO_DATE('2019-05-01','YYYY-MM-DD')), partition p8 values less than (TO_DATE('2019-06-01','YYYY-MM-DD')), partition p9 values less than (TO_DATE('2019-07-01','YYYY-MM-DD')), partition p10 values less than (TO_DATE('2019-08-01','YYYY-MM-DD')) ); insert into range_list_part_tab (seq, deal_date, unit_code, remark) select rownum, to_date(to_char(sysdate-365, 'J') + trunc(DBMS_RANDOM.value(0, 365)),'J'), ceil(dbms_random.value(210,220)), rpad('*', 1, '*') from dual connect by rownum <= 1000; commit;
create table list_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by list (unit_code) ( partition p1 values (211), partition p2 values (212), partition p3 values (213), partition p4 values (214), partition p5 values (215), partition p6 values (216), partition p7 values (217), partition p8 values (218), partition p9 values (219), partition p10 values (220), partition p0 values (DEFAULT) ); alter table list_part_tab split partition p10 at(220) into (PARTITION p11,PARTITION p12);
ALTER TABLE list_part_tab ADD PARTITION P13 VALUES LESS THAN(250);
新增子分區,子分區名稱是P13SUB1
ALTER TABLE list_part_tab MODIFY PARTITION P13 ADD SUBPARTITION P13SUB1 VALUES(350);
ALTER TABLE list_part_tab DROP PARTITION P13;
刪除子分區,子分區名稱P13SUB1
ALTER TABLE list_part_tab DROP SUBPARTITION P13SUB1;
ALTER TABLE list_part_tab TRUNCATE PARTITION P2;
TRUNCATE子分區
ALTER TABLE list_part_tab TRUNCATE SUBPARTITION P13SUB1;
ALTER TABLE list_part_tab MERGE PARTITIONS P1,P2 INTO PARTITION P2;
ALTER TABLE list_part_tab COALESCA PARTITION;
ALTER TABLE SAlist_part_tabLES RENAME PARTITION P11 TO P1;
alter table list_part_tab exchange partition p1 with table range_part_tab including indexs update global indexs;
分區相關查詢
select * from DBA_PART_TABLES
select pt.partitioning_type, pt.subpartitioning_type, pt.partition_count from user_part_tables pt
SELECT tab.* FROM USER_TAB_PARTITIONS tab WHERE TABLE_NAME='LIST_PART_TAB'
select column_name, object_type, column_position from user_part_key_columns where name = 'LIST_PART_TAB';
select sum(bytes / 1024 / 1024) from user_segments where segment_name = 'LIST_PART_TAB';
select partition_name, segment_type, bytes from user_segments where segment_name = 'LIST_PART_TAB';
select segment_name, segment_type, sum(bytes) / 1024 / 1024 from user_segments where segment_name in (select index_name from user_indexes where table_name = 'LIST_PART_TAB') group by segment_name, segment_type;
select table_name, partition_name, last_analyzed, partition_position, num_rows from user_tab_statistics where table_name = 'LIST_PART_TAB';
select table_name, index_name, last_analyzed, blevel, num_rows, leaf_blocks, distinct_keys, status from user_indexes where table_name = 'LIST_PART_TAB';
select index_name, column_name, column_position from user_ind_columns where table_name = 'LIST_PART_TAB';
select ind.index_name, ind.table_name, ind.blevel, ind.num_rows, ind.leaf_blocks, ind.distinct_keys from user_indexes ind where status = 'INVALID';
select a.blevel, a.leaf_blocks, a.index_name, b.table_name, a.partition_name, a.status from user_ind_partitions a, user_indexes b where a.index_name = b.index_name and a.status = 'UNUSABLE';
ps:表格來自《收穫,不止SQL調優》一書做者的整理 操做動做 | 操做命令 | 是否失效(全局索引) |如何避免(全局索引) |是否失效(分區索引)|如何避免(分區索引) ---|--- |---|---|---|--- truncate分區 | alter table part_tab_trunc truncate partition p1 ; | 失效 | alter table part_tab_trunc truncate partition p1 Update GLOBAL indexes; | 沒影響 | N/A drop分區 | alter table part_tab_drop drop partition p1; | 失效 | alter table part_tab_drop drop partition p1 Update GLOBAL indexes; | 沒影響 | N/A split分區 | alter table part_tab_split SPLIT PARTITION P_MAX at(30000) into (PARTITION p3,PARTITION P_MAX); | 失效 | alter table part_tab_split SPLIT PARTITION P_MAX at (30000) into (PARTITION p3,PARTITION P_MAX) update global indexes; | 沒影響 | N/A add分區 | alter table part_tab_add add PARTITION p6 values less than (60000); | 沒影響 | N/A | 沒影響 | N/A exchange分區 | alter table part_tab_exch exchange partition p1 with table normal_tab including indexes; | 失效 | alter table part_tab_exch exchange partition p1 with table normal_tab including indexes update global indexes;| 沒影響 | N/A