(转)Oracle分区表和索引的创建与管理

今天用到了Oracle表的分区,就顺便写几个例子把这个表的分区说一说:

一、创建分区表

1、范围分区

根据数据表字段值的范围进行分区

举个例子,根据学生的不同分数对分数表进行分区,创建一个分区表如下:

create table range_fraction
  (
  id number(8),
  name varchar2(20),
  fraction number(3),
  grade number(2)
)
partition by range(fraction)
(
  partition fraction_60 values less than(60), --不及格
  partition fraction_80 values less than(85), --及格
  partition fraction_100 values less than(maxvalue) --优秀
)

创建完分区表后向表中添加一些数据:

declare
  name     varchar2(10);
  fraction number(5);
  grade    number(5);
  i        number(8):=1;
begin
  for i in 1..100000 LOOP
  SELECT CHR (ROUND (DBMS_RANDOM.VALUE (97, 122))) INTO NAME FROM DUAL;
  SELECT ABS(MOD(DBMS_RANDOM.RANDOM,101)) into fraction FROM DUAL;
  SELECT ABS(MOD(DBMS_RANDOM.RANDOM,10))+1 into grade FROM DUAL;
  insert into range_fraction values(seq_range_fraction.nextval ,name,fraction,grade);
  END LOOP;
end;

查询分区表:

--分别查询所有的,不及格的,中等的,优秀的成绩
select *  from  range_fraction;
select *  from  range_fraction partition(fraction_60) ;
select *  from  range_fraction partition(fraction_80) ;
select *  from  range_fraction partition(fraction_100) ;

当我们的查询语句不指定分区的时候,如果分区字段出现在where条件之后,Oracle会自动根据字段值的范围扫描响应的分区:

select * from range_fraction where fraction<30; 这句SQL执行的时候只会扫描不及格的分区

select * from range_fraction where fraction<80; 这句SQL执行的时候会扫描不及格和中等两个分区

2、散列分区

在范围分区中,分区字段的连续值通常出现在一个分区内,而在散列分区中,连续的字段值不一定存储在相同的分区中。散列分区把记录分布在比范围分区更多的分区上,这减少了I/O争用的可能性。

为了创建一个散列分区,应该用partition by hash语句代替partition by range子句,如下所示:

第一种为各个分区指定不同的表空间,表空间数量不用等于分区数量,当表空间数量大于分区数量的时候会循环写入各个表空间:

create table range_fraction1
  (
  id number(8),
  name varchar2(20),
  fraction number(3),
  grade number(2)
)
partition by hash(fraction)
partitions 8
store in (users,tbs_haicheng)

第二种为每个分区指定一个分区名称并为其指定表空间:

create table range_fraction1
  (
  id number(8),
  name varchar2(20),
  fraction number(3),
  grade number(1)
)
partition by hash(fraction)
(
   partition p1 tablespace tbs_haicheng ,
   partition p2 tablespace users
);

3、列表分区

还可以使用列表分区代替范围分区和散列分区。在列表分区中,告诉Oracle所有可能的值,并指定应当插入相应行的分区。

我们将1、2、3、4班级的数据放在一个分区,将6、7、8的数据放在一个分区,将其他的再放在一个分区,建表如下:

create table range_fraction1
  (
  id number(8),
  name varchar2(20),
  fraction number(3),
  grade number(2)
)
partition by list(grade)
(
   partition p1 values(1,2,3,4) tablespace tbs_haicheng ,
   partition p2 values(5,6,7,8) tablespace users,
   partition p3 values(default)
);

4、组合分区(创建子分区)

即分区的分区。例如可以先进行范围分区,再对各个范围分区创建列表分区。

对于非常大的表来说,这种组合分区是一种把数据分成可管理和可调整的组成部分的有效方法。

举个例子:按照分数范围分区后再将ID散列分区:

create table range_fraction1
  (
  id number(8),
  name varchar2(20),
  fraction number(3),
  grade number(1)
)
partition by range(fraction)
subpartition by hash(id)
subpartitions 4

(
  partition fraction_60 values less than(60), --不及格
  partition fraction_80 values less than(85), --及格
  partition fraction_100 values less than(maxvalue) --优秀
)

二、索引分区

在分区表上可以建立三种类型的索引:1和普通表一样的全局索引;2.全局分区索引;3.本地分区索引

1.建立普通的索引

create index index_fraction on range_fraction(fraction);

2.建立本地分区索引(就是一个索引分区只能对应一个表分区)

create index  local_index_fraction on range_fraction(fraction) local;

3.建立全局分区索引(属于散列索引分区,就是一个索引分区可能指向多个表分区)

create index global_index_fraction on range_fraction(fraction)
GLOBAL partition by  range(fraction)
(
 part_01 values less than(1000),
 part_02 values less than(MAXVALUE)
);

三、管理分区表

1、增加分区

对于范围分区来说,添加一个分区,必须该分区划定的界限高于原来的最大界限,也就是说只能往上加,不能往下加。那么对于用maxvalue关键字创建的范围分区就不能增加分区了

举例:

create table range_fraction
  (
  id number(8),
  name varchar2(20),
  fraction number(3),
  grade number(2)
)
partition by range(fraction)
(
  partition fraction_60 values less than(40), --不及格
  partition fraction_80 values less than(60), --及格
  partition fraction_100 values less than(80) --优秀
)

对于该分区我们增加一个分区:

ALTER TABLE range_fraction ADD PARTITION fraction_100 VALUES LESS THAN (100);

为列表分区添加一个分区:

create table range_fraction
  (
  id number(8),
  name varchar2(20),
  fraction number(3),
  grade number(2)
)
partition by list(grade)
(
   partition p1 values(1,2,3) tablespace tbs_haicheng ,
   partition p2 values(4,5,6) tablespace users
);
ALTER TABLE range_fraction ADD partition p3 VALUES (7,8);

我们再为p3分区新增两个表分区值:

ALTER TABLE range_fraction MODIFY PARTITION p3 ADD VALUES(9,10);

然后再将p3分区的表分区值中的10删掉:

ALTER TABLE range_fraction MODIFY PARTITION p3 DROP VALUES(10);

为哈希分区添加一个子分区:

ALTER TABLE TABLENAME ADD PARTITION PARTNAME;

添加一个子分区的格式:

ALTER TABLE TABLENAME MODIFY PARTITION PARTNAME ADD SUBPARTITION SUBPARTNAME;

2、删除分区

删除分区比较简单,格式如下:

ALTER TABLE ... DROP PARTITION part_name;

3、分区合并

合并父分区格式:

ALTER TABLE TABLENAME MERGE PARTITIONS p1-1, p1-2 INTO PARTITION p1 UPDATE INDEXES;

如果省略了UPDATE INDEXES 的话需要为受影响的分区重建索引

合并子分区的格式:

ALTER TABLE TABLENAME
MERGE SUBPARTITIONS part_1_sub_2, part_1_sub_3 INTO SUBPARTITION part_1_sub_2 UPDATE INDEXES; 

4、转换分区

可以将分区表转换成非分区表,或者几种不同分区表之间的转换。如下:

CREATE TABLE hash_part02 AS SELECT * FROMhash_example WHERE 1=2;
ALTER TABLE hash_example EXCHANGE PARTITIONpart02 WITH TABLE hash_part02;

这时,分区表hash_example中的part02分区的资料将被转移到hash_part02这个非分区表中。

时间: 2024-10-29 05:20:27

(转)Oracle分区表和索引的创建与管理的相关文章

oracle分区表按时间自动创建

表分区是一种思想,分区表示一种技术实现.当表的大小过G的时候可以考虑进行表分区,提高查询效率,均衡IO.oracle分区表是oracle数据库提供的一种表分区的实现形式.表进行分区后,逻辑上仍然是一张表,原来的查询SQL同样生效,同时可以采用使用分区查询来优化SQL查询效率,不至于每次都扫描整个表. 根据年: INTERVAL(NUMTOYMINTERVAL(1,'YEAR'))根据月: INTERVAL(NUMTOYMINTERVAL(1,'MONTH'))根据天: INTERVAL(NUMT

Oracle 分区表中索引失效

当对分区表进行 一些操作时,会造成索引失效. 当有truncate/drop/exchange 操作分区  时全局索引 会失效. exchange 的临时表没有索引,或者有索引,没有用including indexes的关键字,会导致局部的索引失效,就是某个分区失效重建局部索引只能用alter index local_idx rebuild partition p1这样的方式 分区表SPLIT的时候,如果MAX区中已经有记录了,这个时候SPLIT就会导致有记录的新增分区的局部索引失效! 查寻某个

oracle视图和索引

视图和索引 视图 视图的作用 控制数据访问.简化查询.避免重复访问相同的数据 视图的优点 限制用户只能通过视图检索数据,用户看不到底层基表 注意事项 视图可以理解为临时表,会随着真实表的数据变化而自动变化 视图的名字以V_开头,表明是视图; 视图不提高任何效率 视图不占用空间 不是所有的视图都能更改(若改动能对应的原来的表,则可以,否则不可以,比如用了聚合函数的,或者group by而来的) 简单视图 语法 create or replace view 视图名 as select 语句; cre

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

关于分区表和分区索引(About Partitioned Tables and Indexes)对于10gR2而言,基本上可以分成几类: •       Range(范围)分区 •       Hash(哈希)分区 •       List(列表)分区 •       以及组合分区:Range-Hash,Range-List. 对于表而言(常规意义上的堆组织表),上述分区形式都可以应用(甚至可以对某个分区指定compress属性),只不过分区依赖列不能是lob,long之类数据类型,每个表的分区

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

[三思笔记]全面学习Oracle分区表及分区索引 2008-04-15 关于分区表和分区索引(About PartitionedTables and Indexes) 对于 10gR2 而言,基本上可以分成几类: v  Range(范围)分区 v  Hash(哈希)分区 v  List(列表)分区 v  以及组合分区:Range-Hash,Range-List. 对于表而言(常规意义上的堆组织表),上述分区形式都可以应用(甚至可以对某个分区指定 compress 属性),只不过分区依赖列不能是

转:深入学习Oracle分区表及分区索引

转自:http://database.ctocio.com.cn/tips/286/8104286.shtml 关于分区表和分区索引(About Partitioned Tables and Indexes)对于10gR2而言,基本上可以分成几类: Range(范围)分区 Hash(哈希)分区 List(列表)分区 以及组合分区:Range-Hash,Range-List. 对于表而言(常规意义上的堆组织表),上述分区形式都可以应用(甚至可以对某个分区指定compress属性),只不过分区依赖列

oracle sql 基础(五):数据定义语言(创建和管理序列、索引、同义词)

许多应用程序要求使用唯一的数字作为主键的值,你即可以在应用程序中构建代码来处理这种需求,也可以用一个序列来产生唯一的数字.如果你想要增进某些查询的性能,你应该考虑创建一个索引,你也可以用索引在列或列的集合上强制唯一性.你可以用同义词为对象提供可替代的名字.下面我们来介绍序列.索引和同义词三个数据库对象.       一.创建和管理序列 序列是用户创建的数据库对象,可以被多个用户共享. 序列的一个典型的用途是创建一个主键的值,它对于每一行必须是唯一的.序列由一个Oracle内部程序产生并增加或减少

Oracle性能分析8:创建索引

在创建索引时,我们往往希望能够预估索引大小,以评估对现有工程环境的影响,我们也希望创建索引的过程能够最小化的影响我们正在运行的工程环境,并能查看索引的状况. 预估索引大小 预估索引大小,最好的办法是在测试环境中创建它,测试环境最好包含完整的工程环境数据,否则只有通过部分数据来推算完整的索引大小. 如果不能搭建测试环境,Oracle提供了存储过程DBMS_SPACE.CREATE_INDEX_COST来估算索引的大小,下面是一个例子: declare used_bytes number(10);

Oracle性能分析7:创建索引

在创建索引时,我们往往希望可以预估索引大小,以评估对现有project环境的影响,我们也希望创建索引的过程可以最小化的影响我们正在执行的project环境,并能查看索引的状况. 预估索引大小 预估索引大小,最好的办法是在測试环境中创建它,測试环境最好包括完整的project环境数据,否则仅仅有通过部分数据来推算完整的索引大小. 假设不能搭建測试环境,Oracle提供了存储过程DBMS_SPACE.CREATE_INDEX_COST来估算索引的大小,以下是一个样例: declare used_by