分区经过让您将它们分解为更小且更易于管理的分区(称为分区)来解决支持很是大的表和索引的关键问题。不须要修改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