本文参考了

https://blog.csdn.net/mzglzzc/article/details/46300645

一  创建和使用分区表

1.范围分区(RANGE)
范围分区将数据基于范围映射到每一个分区,这个范围是你在创建分区时指定的分区键决定的。这种分区方式是最为常用的,并且分区键经常采用日期。当使用范围分区时,请考虑以下几个规则:
1)每一个分区都必须有一个VALUES LESS THEN子句,它指定了一个不包括在该分区中的上限值。分区键的任何值等于或者大于这个上限值的记录都会被加入到下一个高一些的分区中。
2)所有分区,除了第一个,都会有一个隐式的下限值,这个值就是此分区的前一个分区的上限值。
3)在最高的分区中,MAXVALUE被定义。MAXVALUE代表了一个不确定的值。这个值高于其它分区中的任何分区键的值,也可以理解为高于任何分区中指定的VALUE LESS THEN的值,同时包括空值。

例一:假设有一个CUSTOMER表,表中有数据200000行,我们将此表通过CUSTOMER_ID进行分区,每个分区存储100000行,我们将每个分区保存到单独的表空间中,这样数据文件就可以跨越多个物理磁盘。下面是创建表和分区的代码,如下:

CREATE TABLE CUSTOMER
(
CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY,
FIRST_NAME<span style="white-space:pre"> </span>VARCHAR2() NOT NULL,
LAST_NAME<span style="white-space:pre"> </span>VARCHAR2() NOT NULL,
PHONE<span style="white-space:pre"> </span>VARCHAR2() NOT NULL,
EMAIL<span style="white-space:pre"> </span>VARCHAR2(),
STATUS<span style="white-space:pre"> </span>CHAR()
)
PARTITION BY RANGE (CUSTOMER_ID)
(
PARTITION CUS_PART1 VALUES LESS THAN () TABLESPACE CUS_TS01,
PARTITION CUS_PART2 VALUES LESS THAN () TABLESPACE CUS_TS02
);

例二:按时间划分

CREATE TABLE ORDER_ACTIVITIES
(
ORDER_ID NUMBER() NOT NULL,
ORDER_DATE DATE,
TOTAL_AMOUNT NUMBER,
CUSTOTMER_ID NUMBER(),
PAID CHAR()
)
PARTITION BY RANGE (ORDER_DATE)
(
PARTITION ORD_ACT_PART01 VALUES LESS THAN (TO_DATE('01- MAY -2003','DD-MON-YYYY')) TABLESPACEORD_TS01,
PARTITION ORD_ACT_PART02 VALUES LESS THAN (TO_DATE('01-JUN-2003','DD-MON-YYYY')) TABLESPACE ORD_TS02,
PARTITION ORD_ACT_PART02 VALUES LESS THAN (TO_DATE('01-JUL-2003','DD-MON-YYYY')) TABLESPACE ORD_TS03
);

例三:MAXVALUE

CREATE TABLE RANGETABLE
(
idd INT PRIMARY KEY ,
iNAME VARCHAR(10),
grade INT
)
PARTITION BY RANGE (grade)
(
PARTITION part1 VALUES LESS THEN (1000) TABLESPACE Part1_tb,
PARTITION part2 VALUES LESS THEN (MAXVALUE) TABLESPACE Part2_tb
); --——在表上执行查询
select * from RANGETABLE; --——在表分区上执行查询
select * from RANGETABLE partition(part1);

  

2.列表分区(LIST)
该分区的特点是某列的值只有几个,基于这样的特点我们可以采用列表分区。创建一个按字段数据列表固定可枚举值分区的表。插入记录分区字段的值必须在列表中,否则不能被插入。

例一:

CREATE TABLE PROBLEM_TICKETS
(
PROBLEM_ID NUMBER(7) NOT NULL PRIMARY KEY,
DESCRIPTION VARCHAR2(2000),
CUSTOMER_ID NUMBER(7) NOT NULL,
DATE_ENTERED DATE NOT NULL,
STATUS VARCHAR2(20)
)
PARTITION BY LIST (STATUS)
(
PARTITION PROB_ACTIVE VALUES ('ACTIVE') TABLESPACE PROB_TS01,
PARTITION PROB_INACTIVE VALUES ('INACTIVE') TABLESPACE PROB_TS02
);

  

例二:

CREATE TABLE ListTable
(
id INT PRIMARY KEY ,
name VARCHAR (20),
area VARCHAR (10)
)
PARTITION BY LIST (area)
(
PARTITION part1 VALUES ('guangdong','beijing') TABLESPACE Part1_tb,
PARTITION part2 VALUES ('shanghai','nanjing') TABLESPACE Part2_tb
);

  

3.哈希分区(散列分区)(HASH)
例一:

CREATE TABLE HASH_TABLE
(
COL NUMBER(8),
INF VARCHAR2(100)
)
PARTITION BY HASH (COL)
(
PARTITION PART01 TABLESPACE HASH_TS01,
PARTITION PART02 TABLESPACE HASH_TS02,
PARTITION PART03 TABLESPACE HASH_TS03
)

  

简写:

CREATE TABLE emp
(
empno NUMBER (4),
ename VARCHAR2 (30),
sal NUMBER
)
PARTITION BY HASH (empno) PARTITIONS 8
STORE IN (emp1,emp2,emp3,emp4,emp5,emp6,emp7,emp8);

  

hash分区最主要的机制是根据hash算法来计算具体某条纪录应该插入到哪个分区中,hash算法中最重要的是hash函数,Oracle中如果你要使用hash分区,只需指定分区的数量即可。建议分区的数量采用2的n次方,这样可以使得各个分区间数据分布更加均匀。

4.组合分区(RANGE-LIST 和 RANGE-HASH)
1)基于范围分区和列表分区,表首先按某列进行范围分区,然后再按某列进行列表分区,分区之中的分区被称为子分区。

CREATE TABLE emp
(
empno NUMBER (4),
ename VARCHAR2 (30),
sal NUMBER
)
PARTITION BY HASH (empno) PARTITIONS 8
STORE IN (emp1,emp2,emp3,emp4,emp5,emp6,emp7,emp8);

  

2)基于范围分区和散列分区,表首先按某列进行范围分区,然后再按某列进行散列分区。

create table dinya_test
(
transaction_id number primary key,
item_id number(8) not null,
item_description varchar2(300),
transaction_date date
)
partition by range(transaction_date)
subpartition by hash(transaction_id) subpartitions 3 store in (dinya_space01,dinya_space02,dinya_space03)
(
partition part_01 values less than(to_date(‘2006-01-01','yyyy-mm-dd')),
partition part_02 values less than(to_date(‘2010-01-01','yyyy-mm-dd')),
partition part_03 values less than(maxvalue)
); CREATE TABLE range_hash_example(
range_column_key int,
hash_column_key INT,
DATA <span style="white-space:pre"> </span>VARCHAR2(20)
)
PARTITION BY RANGE(range_column_key)
SUBPARTITION BY HASH(hash_column_key) SUBPARTITIONS 2
(
PARTITION part_1 VALUES LESS THAN (100000000)
(
SUBPARTITION part_1_sub_1,
SUBPARTITION part_1_sub_2,
SUBPARTITION part_1_sub_3
),
PARTITION part_2 VALUES LESS THAN (200000000)
(
SUBPARTITION part_2_sub_1,
SUBPARTITION part_2_sub_2
)
);

  

--注: subpartitions 2 并不是指定subpartition的个数一定为2,实际上每个分区的子分区个数可以不同。如果不指定subpartition的具体明细,则系统按照subpartitions的值指定subpartition的个数生成子分区,名称由系统定义 。

二  有关分区表的维护操作
1.添加分区
以下代码给SALES表添加了一个P3分区
ALTER TABLE SALES ADD PARTITION P3 VALUES LESS THAN(TO_DATE('2003-06-01','YYYY-MM-DD'));
注意:以上添加的分区界限应该高于最后一个分区界限。
以下代码给SALES表的P3分区添加了一个P3SUB1子分区
ALTER TABLE SALES MODIFY PARTITION P3 ADD SUBPARTITION P3SUB1 VALUES('COMPLETE');

-- range partitioned table
ALTER TABLE range_example ADD PARTITION part04 VALUES LESS THAN (TO_DATE('2008-10-1 00:00:00','yyyy-mm-ddhh24:mi:ss'));

--list partitioned table
ALTER TABLE list_example ADD PARTITION part04 VALUES('TE');

--Adding Values for a List Partition
ALTER TABLE list_example MODIFY PARTITION part04 ADD VALUES('MIS');

--Dropping Values from a List Partition
ALTER TABLE list_example MODIFY PARTITION part04 DROP VALUES('MIS');

--hash partitioned table
ALTER TABLE hash_example ADD PARTITION part03;

--增加subpartition
ALTER TABLE range_hash_example MODIFY PARTITION part_1 ADD SUBPARTITION part_1_sub_4;

注:hash partitioned table新增partition时,现有表的中所有data都有重新计算hash值,然后重新分配到分区中,所以被重新分配的分区的indexes需要rebuild 。

2.删除分区
ALTER TABLE SALES DROP PARTITION P3;

ALTER TABLE SALES DROP SUBPARTITION P4SUB1;
注意:如果删除的分区是表中唯一的分区,那么此分区将不能被删除,要想删除此分区,必须删除表。

3.截断分区
截断某个分区是指删除某个分区中的数据,并不会删除分区,也不会删除其它分区中的数据。当表中即使只有一个分区时,也可以截断该分区。通过以下代码截断分区:
ALTER TABLE SALES TRUNCATE PARTITION P2;
通过以下代码截断子分区:
ALTER TABLE SALES TRUNCATE SUBPARTITION P2SUB2;

4.合并分区
合并分区是将相邻的分区合并成一个分区,结果分区将采用较高分区的界限,值得注意的是,不能将分区合并到界限较低的分区。
ALTER TABLE SALES MERGE PARTITIONS P1,P2 INTO PARTITION P2 UPDATE INDEXES;
--如果省略update indexes子句的话,必须重建受影响的分区的index;
ALTER TABLE range_example MODIFY PARTITION part02 REBUILD UNUSABLE LOCAL INDEXES;

5.拆分分区
拆分分区将一个分区拆分两个新分区,拆分后原来分区不再存在。注意不能对HASH类型的分区进行拆分。
ALTER TABLE SALES SBLIT PARTITION P2 AT(TO_DATE('2003-02-01','YYYY-MM-DD')) INTO (PARTITION P21,PARTITION P22);
注意:如果是RANGE类型的,使用at,LIST类型的使用values。

6.接合分区(coalesce)
分区接合是针对散列分区或者*-散列子分区的,目的是减少分区数。当某个散列分区接合后,Oracle将其分区的数据分散到其它分区中。被接合的分区是由数据库选择的,接合完成后该分区会被删除,且如果没有使用UPDATE INDEX子句,本地索引和全局索引均将变成不可用,一般需要重建索引。
--散列分区表的散列分区接合
ALTER TABLE table_name COALESCE PARTITION;
--散列分区表的散列子分区接合
ALTER TABLE table_name MODIFY PARTITION partition_name COALESCE SUBPARTITION;
(网上搜索90%的资料都是    接合分区coalesca    然后介绍就一句话和一句SQL……这个词都拼错了好么?!)

7.重命名表分区
ALTER TABLE table_name RENAME PARTITION old_name TO new_name;
ALTER TABLE table_name RENAME SUBPARTITION old_name TO new_name;

8.交换分区
可以将一个分区(子分区)和非分区表进行数据交换,oracle交换的方法是其实是对逻辑存储段进行交换。同样,散列|范围|列表分区可以与复合*-散列|*-范围|*-列表分区间也可以进行数据交换。当应用中需要将非分区表的数据转换进入分区表的分区时非常高效实用。使用INCLUDEING INDEXES子句可以同步将本地索引也进行交换,使用WITH VALIDATATION子句还可以实现行数据的验证。
交换分区时如果不带UPDATE INDEXES子句,则全局索引或全局索引基于的分区将变为不可用。
1)三种单级分区与非分区表的交换
ALTER TABLE table_name EXCHANGE PARTITION partition_name WITH TABLE nonpartition_name;
2)单级散列分区表与复合*-散列分区的交换
此时要求单级散列分区表的分区键与复合*-散列分区表的子分区键相同,且两个交换的散列分区数也得相同,此外也不能指定单级散列分区表的某一个分区进行交换。
3)复合*-散列分区中的散列子分区交换
使用ALTER TABLE ... EXCHANGE SUBPARTITION与非分区表进行交换,且只能跟非分区表进行交换。
4)单级列表分区表与复合*-列表分区的交换
此时要求List分区表的分区键和*-List表的子分区键相匹配,前者的List分区数与后者的List子分区相同。
5)复合*-列表分区中的列表子分区交换
同样也是使用ALTER TABLE ... EXCHANGE SUBPARTITION与非分区表进行交换,且只能跟非分区表进行交换。
6)单级范围分区表与复合*-范围分区表的交换
此时要求Range分区表的分区键和*-Range表的子分区键相匹配,前者的Range分区数与后者的Range子分区相同。
7)复合*-范围分区中的范围子分区交换
同样也是使用ALTER TABLE ... EXCHANGE SUBPARTITION与非分区表进行交换,且只能跟非分区表进行交换。

9.移动分区
alter table custaddr move partition P_OTHER tablespace system;
alter table custaddr move partition P_OTHER tablespace icd_service;
分区移动会自动维护局部分区索引,oracle不会自动维护全局索引,所以需要我们重新rebuild分区索引,具体需要rebuild哪些索引,可以通过dba_part_indexes,dba_ind_partitions去判断。
Select index_name,status From user_indexes Where table_name='CUSTADDR';

10.关于分区表和索引
1)本地分区索引
本地分区索引是使用了LOCAL属性创建的分区索引,其特征是索引分区的所有键均指向其基表某个 唯一分区中存储的相应行。Oracle创建本地分区索引的目的就是要确保索引也是分区管理的,而且索引的分区与表的分区是均衡的,也就是本地分区索引具有与其基表相同的分区、子分区,即分区键等同于表的分区键、分区数等同于表的分区数。
任何基表分区的增加、删除、合并、分割操作,或者散列分区增加或合并操作,Oracle会通过其自身的机制自动维护本地分区索引相应的分区,此即本地分区索引与基表的均衡性原则。
如果分区列能够形成索引列的一个子集,则本地分区索引可以是唯一索引。该限制能确保具有相同索引键的行始终映射到同一个分区,在该分区中,违反唯一性的行为能被检测到。
本地索引的优势有:
l在基表上执行除SPLIT PARTITION或ADD PARTITION 外的维护命令仅仅只有一个分区会被影响
l当分区表只有一个本地分区索引时,对分区进行维护操作的时间是与分区的大小成正比的
l本地分区索引支持分区的独立性
l只能本地分区索引支持单一分区数据的装入和卸出
l本地索引与基表的均衡性会给Oracle执行计划带来更好的性能
l表分区和各自的本地索引可以同时恢复
l分区表中的位图索引必须是本地索引,非分区表上不能建立分区位图索引
①本地前缀索引
本地前缀索引是指以索引列的左前缀来分区的,如果存在子分区则要求其子分区的分区键包含在索引键中。本地前缀索引可以是唯一索引,也可以是非唯一索引。
②本地非前缀索引
本地非前缀索引是指没有以索引列的左前缀来分区的,或者是以索引列的左前缀来分区,但子分区的分区键不在索引键中。本地非前缀索引不可以是唯一索引,除非分区键是索引键的子集(此时是前缀索引)。

2)全局分区索引
全局分区索引是指某个特定索引分区中的键可能指向存储在基表中的多个分区或子分区中的行,其创建需要使用GLOBAL属性。无论分区表是那种类型的分区,全局索引只支持按范围和散列分区两种分区方式。
全局索引往往与基表是不均衡的,如果要追求二者的均衡性,只能使用本地分区索引。全局分区的索引类型只能是b-tree索引,不能是bitmap索引。正是因为其是b-tree索引,所以无论其指向多少个分区抑或多少行,也只有一个b-tree入口,每个索引分区中会再包含指向具体表分区或子分区中的行的键。
全局分区索引必须是前缀的,不支持非前缀的。其中,前缀的意思和本地分区索引的前缀的含义相同,即“前缀索引是指以索引列的左前缀来分区的”。

管理全局分区索引
l当基表分区移动和删除(TRUNCATE、DROP、MOVE、SPLIT)时,全局索引的所有分区都受影响,也不支持分区依赖
l当基表分区或子分区恢复到某个时间点时,全局索引中所有相应入口也要恢复到相同的时间点。由于索引的分区或子分区的入口可能离散分布,其它分区或子分区混合型入口不恢复,除了重建索引之外没有办法完成

以表range_example为例:

1)建立普通的索引
create index com_index_range_example_id on range_example(id); 2)建立本地分区索引
create index local_index_range_example_id on range_example(id) local; 3)建立全局分区索引
create index gidx_range_example_id on range_example(id)
GLOBAL partition by range(id)
(
part_01 values less than(1000),
part_02 values less than(MAXVALUE)
);
对于分区索引的删除,local index 不能指定分区名称,单独的删除分区索引。local index 对应的分区会伴随着data分区的删除而一起被删除。 global partition index 可以指定分区名称,删除某一分区。但是有一点要注意,如果该分区不为空,则会导致更高一级的索引分区被置为UNUSABLE 。 ALTER INDEX gidx_range_exampel_id drop partition part_01 ;
此句将导致part_02 状态为UNUSABLE

  

注意:对于表分区的各种操作,一定要注意更新索引

三  相关查询
1.跨分区查询

注意查询分区相关信息所有表名用户名需大写,具体看数据库配置
select sum( *) from
(select count(*) cn from t_table_SS PARTITION (P200709_1)
union all
select count(*) cn from t_table_SS PARTITION (P200709_2)
); 2.查询表上有多少分区
SELECT * FROM USER_TAB_PARTITIONS WHERE TABLE_NAME='tableName'; 3.查询索引信息
select object_name,object_type,tablespace_name,sum(value)
from v$segment_statistics
where statistic_name IN ('physical reads','physical write','logical reads')and object_type='INDEX'
group by object_name,object_type,tablespace_name
order by 4 desc --显示数据库所有分区表的信息:
select * from DBA_PART_TABLES --显示当前用户可访问的所有分区表信息:
select * from ALL_PART_TABLES --显示当前用户所有分区表的信息:
select * from USER_PART_TABLES --显示表分区信息 显示数据库所有分区表的详细分区信息:
select * from DBA_TAB_PARTITIONS --显示当前用户可访问的所有分区表的详细分区信息:
select * from ALL_TAB_PARTITIONS --显示当前用户所有分区表的详细分区信息:
select * from USER_TAB_PARTITIONS --显示子分区信息 显示数据库所有组合分区表的子分区信息:
select * from DBA_TAB_SUBPARTITIONS --显示当前用户可访问的所有组合分区表的子分区信息:
select * from ALL_TAB_SUBPARTITIONS --显示当前用户所有组合分区表的子分区信息:
select * from USER_TAB_SUBPARTITIONS --显示分区列 显示数据库所有分区表的分区列信息:
select * from DBA_PART_KEY_COLUMNS --显示当前用户可访问的所有分区表的分区列信息:
select * from ALL_PART_KEY_COLUMNS --显示当前用户所有分区表的分区列信息:
select * from USER_PART_KEY_COLUMNS --显示子分区列 显示数据库所有分区表的子分区列信息:
select * from DBA_SUBPART_KEY_COLUMNS --显示当前用户可访问的所有分区表的子分区列信息:
select * from ALL_SUBPART_KEY_COLUMNS --显示当前用户所有分区表的子分区列信息:
select * from USER_SUBPART_KEY_COLUMNS --怎样查询出oracle数据库中所有的的分区表
select * from user_tables a where a.partitioned='YES' --删除一个表的数据是
truncate table table_name; --删除分区表一个分区的数据是
alter table table_name truncate partition p5;

  


												




											

oracle分区表的使用和查询的更多相关文章

  1. Oracle分区表做跨分区查询

    问:有一张大表,其中按时间字段(TIME_ID)进行表分区(按季度分区),但是如果业务人员做跨季度的大批量数据的查询时,未能走TIME_ID分区索引,导致全表扫描.此种情况该如何处理? 示例解析: 1 ...

  2. 谈一下如何设计Oracle 分区表

    在谈设计Oracle分区表之间先区分一下分区表和表空间的个概念: 表空间:表空间是一个或多个数据文件的集合,所有数据对象都存放在指定的表空间中,但主要存放表,故称表空间. 分区表:分区致力于解决支持极 ...

  3. 深入学习Oracle分区表及分区索引

    关于分区表和分区索引(About Partitioned Tables and Indexes)对于10gR2而言,基本上可以分成几类: •       Range(范围)分区 •       Has ...

  4. oracle 分区表和分区索引

    很复杂的样子,自己都没有看完,以备后用 http://hi.baidu.com/jsshm/item/cbfed8491d3863ee1e19bc3e ORACLE分区表.分区索引ORACLE对于分区 ...

  5. 谈一下怎样设计Oracle 分区表

    在谈设计Oracle分区表之间先区分一下分区表和表空间的个概念: 表空间:表空间是一个或多个数据文件的集合,全部数据对象都存放在指定的表空间中,但主要存放表,故称表空间. 分区表:分区致力于解决支持极 ...

  6. ORACLE分区表、分区索引详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt160 ORACLE分区表.分区索引ORACLE对于分区表方式其实就是将表分段 ...

  7. 【三思笔记】 全面学习Oracle分区表及分区索引

    [三思笔记]全面学习Oracle分区表及分区索引 2008-04-15 关于分区表和分区索引(About PartitionedTables and Indexes) 对于 10gR2 而言,基本上可 ...

  8. oracle分区表彻底删除的办法,处理删不掉的不规则表名

    Oracle分区表彻底删除的办法当对一个不再使用的分区表进行drop后,查询user_tab_partitions视图发现出现如下不规则的分区表表名:SQL> select distinct t ...

  9. Oracle分区表常见操作

    Oracle分区表常用于业务中大表使用,如历史交易记录表等,提高表记录查询效率.本文主要描述范围分区表的创建.新增以及索引创建. Oracle操作分区表相关信息 显示数据库所有分区表的信息:DBA_P ...

随机推荐

  1. Maven(一)

    Maven学习总结(一)——Maven入门 一.Maven的基本概念 Maven(翻译为"专家","内行")是跨平台的项目管理工具.主要服务于基于Java平台的 ...

  2. PHP 判断协议是否为HTTPS

    if ($_SERVER['HTTPS'] != "on") { echo "This is not HTTPS"; }else{ echo "Thi ...

  3. Day15 HTML补充、初识JavaScript

    一.上节回顾 上节回顾: HTML 头部信息:编码.title.style.link(导入css文件) 身体: 内联 块级 --->inline-block(既有内联效果又有块级效果) a标签: ...

  4. 9.21 investments - chapter 4 - Summary

    转载请注明来自souldak,微博:@evagle MUTUAL FUNDS AND OTHER INVESTMENT COMPANIES KEYWORDS: investment company n ...

  5. GIT入门笔记(18)- 标签创建和管理

    git tag <name>用于新建一个标签,默认为HEAD,也可以指定一个commit id: git tag -a <tagname> -m "blablabla ...

  6. gdb cheat sheet

    0x01 控制流 r run,运行程序. r < a.txt   run,重定向输入 si   step instruction 进入函数 ni      next instruction 下一 ...

  7. fiddler抓包工具

    转载: http://www.cr173.com/html/15341_1.html https://www.cnblogs.com/shihaiming/p/5887654.html 软件简介: 数 ...

  8. [HAOI2017]供给侧改革[离线、trie]

    题意 题目链接 分析 由于数据随机所以 LCP 不会很长,维护每个位置后 40 个字符构成的01串. 将询问离线维护,以当前右端点为 R 的每个长度的 LCP 的第一个出现位置 f(这个信息显然是单调 ...

  9. 病毒木马查杀实战第020篇:Ring3层主动防御之基本原理

    前言 假设说我们的计算机中安装有杀毒软件,那么当我们有意或无意地下载了一个恶意程序后.杀软一般都会弹出一个对话框提示我们,下载的程序非常可能是恶意程序,建议删除之类的.或者杀软就不提示.直接删除了:或 ...

  10. 利用React Native 从0到1 开发一款兼容IOS和android的APP(仿造京东)

    最近有一部电视剧叫做<微微一笑很傻逼>里面有个男猪脚,人们都叫他大神~我觉得吧~大神是相对的~所以~啥事都得谦虚! 好了 今天介绍的是如何从0到1利用React Native开发一款兼容I ...