ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 教你如何成为Oracle 10g OCP - 第九章 对象管理(3)

教你如何成为Oracle 10g OCP - 第九章 对象管理(3)

原创 Linux操作系统 作者:tolywang 时间:2011-01-27 14:34:46 0 删除 编辑


分区表及分区索引的管理 --

http://space.itpub.net/35489/viewspace-668041

local 索引的维护会在oracle 操作表分区的时候自动进行,需要注意的是global
索引,当global索引所在表执行alter table 涉及下列操作时,会导致该索引失效:
 ADD PARTITION | SUBPARTITION
 COALESCE PARTITION | SUBPARTITION
 DROP PARTITION | SUBPARTITION
 EXCHANGE PARTITION | SUBPARTITION
 MERGE PARTITION | SUBPARTITION
 MOVE PARTITION | SUBPARTITION
 SPLIT PARTITION | SUBPARTITION
 TRUNCATE PARTITION | SUBPARTITION

因此,建议用户在执行上述操作sql 语句后附加update indexes 子句,oracle
即会自动维护全局索引,当然,需要注意这中间有一个平衡,你要平衡操作ddl的
时间和重建索引哪个时间更少,以决定是否需要附加update indexes 子句。

 


分区表的管理 --


1. 增加表分区(add partition) 

增加表分区适用于所有的分区形式,语法:alter table tab_name add partition..


对于像list,range 这种存在范围值的分区,所要增加的分区值必须要大于当前分
区中的最大值(但是如果当前存在maxvalue 或default 的分区,add partition
会报错,这种情况只能使用split,后面会讲到),hash 分区则无此限制。
例子:
alter table test_range add partition p6 values less than (120000) tablespace tbs06 ;
alter table test_list add partition p12 values ('50','100') tablespace tbs02 ;
alter table test_hash add partition ; 

注意:

(1)、对于hash 分区,当你执行add partition 操作的时候,oracle 会自动选择一个
分区,并重新分配部分记录到新建的分区,这也意味着有可能带来一些IO 操作,但
是执行操作的过程可能很快结束,只是数据重新分配还在后台进行,具体参考:
http://www.itpub.net/thread-1390083-1-1.html

(2)、执行alter table add partition 时未指定update indexes 子句:
  如果是range/list分区,其local 索引和global 索引不会受影响(未发生数据移动);
  如果是hash 分区,新加分区及有数据移动的分区的local 索引和global索引会被
  置为unuseable,需要重新编译。具体可以参考测试:
http://space.itpub.net/35489/viewspace-684473   

(3)、复合分区完全适用上述所述规则。

 


2. 拆分表分区(split partition) 

比较常用的split是对default或maxvalue进行拆分,不过如果你发现非maxvalue/
default分区某分区过大,也可以通过split的方式对这些分区进行拆分。

该命令的语法针对不同分区有不同的形式:
range partition : alter table tbname split partition ptname at (value) into (partition newpt1
tbs_clause,partition newpt2 tbs_clause);
list partition : alter table tbname split partition ptname values (v1,v2...vn) into (partition newpt1
tbs_clause,partition newpt2 tbs_clause);
上述两项,如果是操作子分区,则将partition 关键字换成subpartition 即可。旧分区
中符合新定义值的记录会存储到指定的第一个分区中,其它的记录存储到第二个分区。

例子:

CREATE TABLE DFMS.TEST04
PARTITION BY RANGE(OBJECT_ID)

  PARTITION P1 VALUES LESS THAN (2000)  TABLESPACE TBS01, 
  PARTITION P2 VALUES LESS THAN (8000)  TABLESPACE TBS02,
  PARTITION P3 VALUES LESS THAN (20000) TABLESPACE TBS03,
  PARTITION P4 VALUES LESS THAN (40000) TABLESPACE TBS04,
  PARTITION PMAX VALUES LESS THAN (MAXVALUE)  TABLESPACE TBS05
)
AS SELECT * FROM DBA_OBJECTS ;


alter table test04 split partition pmax at (80000) into 
(partition p5 tablespace log_data ,
 partition pmax  tablespace log_data); 

备注: 这里的pmax并不是旧的pmax, 其实这里的pmax也可以写成p6, 只是
新的pmax(或p6)对应的值都是maxvalue(值范围不变,名字可以任意起) .


a. split partition/subpartition不能用于hash分区或hash子分区。
b. split partition/subpartition 视被分割的分区数据量多少,可能需要花费
不小的代价,相当于该分区数据的全扫描,除了:
 (1). split后的两个分区中,至少一个是空的,且非空那个分区的存储属性
与split前的存储属性完全相同。
 (2). 如果split的分区包含blob字段,split后非空的那个分区中字段的存储属性
也必须与split前的存储属性完全相同。

 


split分区对于索引的影响:

A. split新分区中有数据时

拆分(split)后, 旧分区中符合less than 80000的留在了第一个分区p5(新分区),
其他的都存在第二个分区(新的pmax分区)。 由于这里触发了数据的移动,global
index 变成UNUSABLE(失效),因为发生数据移动的只是新的p5和pmax分区,所以
本地索引分区中p5及pmax对应的本地索引变成无效UNUSABLE, 其他分区还是USABLE.

alter index PK_ID rebuild online; 
alter index IDX1_TEST04 rebuild partition p5 online; 
alter index IDX1_TEST04 rebuild partition pmax online;
查询dba_indexes及dba_ind_partitions可以看到索引变成valid及USABLE状态了。

B. split新分区中没有数据时

比如我们再加入一个分区,表中值最大是100000,所以新的pmax中没有数据。
alter table test04 split partition pmax at (200000) into 
(partition p6 tablespace log_data , partition pmax  tablespace log_data); 
查看global index及local index可以看到全局索引及每个本地索引分区都是
USABLE, 这是因为没有触发数据移动 。 注意因为这里是表空间没有变化,
如果非空的分区存储属性和原来的存储属性不一样,也会发生数据移动,也会导致
索引失效。

虽然存在几种情况,但是我们在做完一些分区表的操作后,最好都能查询一下全局
及本地分区索引的状态,以免出现异常。 

 

3. Drop表分区(drop partition) 

删除表分区包含两种操作,分别是:
a. 删除分区:  alter table table_name drop partition [partition_name] ;
b. 删除子分区:alter table table_name drop subpartition [subpartition_name] ; 
除了hash分区和hash子分区外,其他的分区格式都可以支持这项操作。drop partition
时该分区内存储的数据也将同时删除。

如果用户只是想删除指定的分区但保留数据,你应该使用merge partition .

同样,如果执行drop partition时候没有指定update indexes子句时,可能对全局
及本地分区索引造成影响。如果删除的分区没有数据,不涉及到数据变化,那么
全局及本地分区索引不受到影响(不失效); 如果删除的分区有数据,既不保留分区
也不保留数据,那么删除分区时对应的本地索引分区也同时被删除,不受影响,但是
全局索引会失效。具体测试见:
http://space.itpub.net/35489/viewspace-684473 

 

4. 截断表分区(Truncate Partition)

Truncate partition 就像truncate table 一样,直接从头部截断数据。在不指
定update indexes 子句的情况下,truncate partition 也会造成分区所在表的
global 索引失效。语法非常简单:
alter table tbname truncate partition/subpartition ptname;

alter table test04 truncate partition p6 ;
查询
select * from dba_indexes where index_name='PK_ID' ;
select * from dba_ind_partitions where index_name='IDX1_TEST04' ;
发现global index索引失效,本地分区索引状态都是USABLE, 当然如果这个分区
中本来就没有数据,那么本地及全局索引都不受影响。 

 

5. 合并表分区(Merge Partition)
将两个分区合并为一个,适用于除hash分区外的其他分区形式(hash分区采用
coalesce partition), 需要注意的是要合并的两个分区必须是连续的,这是
由分区本身的特性决定的。

语法:
alter table tab_name merge partitions/subpartitions pt1,pt2
into partition/subpartition pt3 ; 

同样也可以接update indexes子句以避免单独执行造成索引失效的问题。

例子:
alter table test04 merge partitions p4,p5 into partition p4
tablespace log_data ;
ORA-14275: 不能将下界分区作为结果分区重用 

alter table test04 merge partitions p4,p5 into partition p7
tablespace log_data ; 
名称修改为新的p7, 建立完成后,因为仅仅是合并分区,没有发生数据移动,
所以全局及本地分区索引都没有受到影响。

 

6. 修改list表分区 - add/drop values

alter table tab_name modify partition/subpartition part_name add
values (v1,v2,v3.....vn) ; 

例子:
alter table test06 modify partition p3 add values(29,31) ; 

需要注意的是,添加的新value不能存在于当前任何分区list值中,当前表中也不能
存在数据为新加入的value的记录,特别是当我们建立了default分区的时候,有必
要先检查一下当前表不存在要添加的值,不然命令执行会报错。

注意: 增加新的list值不会影响表中原有的记录,不会对index造成影响。 

drop values正好相反,该命令是用来删除指定分区的value值,语法:
alter table tab_name modify partition/subpartition part_name drop value(v1,v2...vn);
同样在删除list分区value列值的时候,也必须确认当前分区存在指定的value值,
但是没有任何应用该值的记录(即对应这个value没有数据存在表中)。  

alter table test06 modify partition p3 drop values(29) ;  

 

7.  移动表分区(move partition)

和move table的操作很类似,有时也非常有用,比如降低行迁移,经常用来修改分区
所在表空间。
alter table test04 move partition t3 tablespace tbs05 ;

和move table一样,move partition/subpartition会锁表,如果没有指定update
indexes的话,则被移动分区所在的local index以及全局索引都会失效,需要进行
rebuild.

 

8.  重命名表分区(Rename partition) 
alter table tab_name rename partition part_name to new_part_name ;
例子:
alter table test04  rename partition p3 to p12 ;


9.  修改表分区当前属性(Rename partition) ,
即修改即生效,不过所在表空间改不了(需要用到move partition). 比较少用。


10.  修改表分区默认属性(Rename partition)
对于当前表和分区的存储参数没有影响,只有修改过之后,当你下次再添加分区
时,在非手工显式指定分区参数的情况下,新分区默认使用你当前指定的存储参数。

A. 修改表属性,适用于range,list,hash分区形式(hash分区只能修改默认表空间参数)
例如:
alter table test04 modify default attributes tablespace tbs001 ;
B. 修改分区属性,适用于组合分区
例如:
alter table test04 modify default attributes for partition p5 tablespace tbs003;

 

分割(splitting),移除(dropping ),及融合(merging)等操作不适用于
哈希分区。但对哈希分区可以进行添加(add)及接合(coalesce)操作。

 

 

分区索引的管理 -- 


A. 增加索引分区 (add index partition)
注意: 增加索引分区仅仅是针对非local分区索引而言的。

alter index idx_name add partition part_name tablespace xxx ;
增加分区只能用于hash的global索引(如果想为range类型的索引增加分区,不要
用add, 使用split)。add partition无法新增local索引分区,因为local分区是
由索引所在基表来维护的(分区表在增加分区的时候index分区也会自动增加)。

例子:alter index idx_test03_id add partition p8 tablespace tbs8;


B. 删除索引分区(drop index partitions)
alter index idx_name drop partition part_name ;
这里是删除索引的分区,索引分区的数据不会删除,会转移。

要注意的是,索引必须拥有一个maxvalue的分区,该分区无法删除。另外,删除
的索引分区中包含数据,分区被删除后,会造成相邻的higher分区失效,需要手工
编译。因为索引中数据都是经过排序的,drop partition删除的是索引的分区,但
对应的索引数据还需要有地方存放(不然索引就不准确了),于是就只好存储到比它
更高区间值的索引分区里去了,那个分区莫名其妙多了数据,自然状态就变成不可
用了。


C. 重新rebuild索引分区
alter index idx_name rebuild partition/subpartition part_name ;
其中global索引只支持range分区,local索引没有限制。一般对于索引进行
rebuild都是在对分区表进行一些操作导致数据移动后进行,如果分区表操作
指定了update indexes子句,无效索引分区自动rebuild .

对于local索引分区,还可以使用下面的命令方式:
alter table tab_name modify partition/subpartition part_name
rebuild unusable local index ; 

查看分区索引是否失效的视图: dba_ind_partitions

 

D. 重命名索引分区
语法:
alter index idx_name rename partition/subpartition ptname to ptnewname ;
global索引只支持range分区,local索引没有限制。
 

E. Split索引分区
alter index idx_name split partition ptname at (value)
into (partition pt1 tableclause, partition pt2 tbsclause) ;

例子:
alter index idx_test04_id split partition i_p8 at (2000) into
  (partition i_p8 tablespace tbs02
   partition i_p9 tablespace tbs05); 


F. 修改索引分区默认属性
与修改表分区的操作类似,不过对于global索引,只能修改range分区,local
索引无限制。
alter index idx_name modify default attributes for partition ptname ;


G. 修改索引分区当前属性 
类似表分区当前属性。


-------------------------------------------------
会导致global index及local index失效的测试:
http://space.itpub.net/35489/viewspace-684473 

分区表及分区索引[final]
http://space.itpub.net/35489/viewspace-668041
-------------------------------------------------

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-686378/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle , MySQL, SAP IQ, SAP HANA, PostgreSQL, Tableau 技术讨论,希望在这里一起分享知识,讨论技术,畅谈人生 。

注册时间:2007-12-10

  • 博文量
    5595
  • 访问量
    13740172