您当前的位置: 首页 > 数据库教程 > Oracle教程 > Oracle分区之四:分区维护和管理

Oracle分区之四:分区维护和管理

作者:不详 来源:网络 发布时间: 2014-08-26 11:13 点击:
一,分区表的相关实验 创建一个列表分区表 create table t3(id number,city varchar2(10)) partition by list(city) ( partition p1 values ('SH','JS','ZJ') , partition p2 values ('BJ','TJ','HB') , partition p3 values ('GZ','SZ') , partition p_others values

Oracle分区之四:分区维护和管理

  一,分区表的相关实验

  创建一个列表分区表

  create table t3(id number,city varchar2(10))

  partition by list(city)

  (

  partition p1 values ('SH','JS','ZJ') ,

  partition p2 values ('BJ','TJ','HB') ,

  partition p3 values ('GZ','SZ') ,

  partition p_others values (default)

  );

  create or replace procedure proc1

  as

  begin

  for i in 1..1000

  loop

  execute immediate

  'INSERT INTO T3 values(:x,:y)' USING i,'SH';

  end loop;

  end;

  /

  exec proc1

  create or replace procedure proc1

  as

  begin

  for i in 1001..2000

  loop

  execute immediate

  'INSERT INTO T3 values(:x,:y)' USING i,'JS';

  end loop;

  end;

  /

  exec proc1

  create or replace procedure proc1

  as

  begin

  for i in 2001..3000

  loop

  execute immediate

  'INSERT INTO T3 values(:x,:y)' USING i,'ZJ';

  end loop;

  end;

  /

  exec proc1

  create or replace procedure proc1

  as

  begin

  for i in 3001..4000

  loop

  execute immediate

  'INSERT INTO T3 values(:x,:y)' USING i,'BJ';

  end loop;

  end;

  /

  exec proc1

  create or replace procedure proc1

  as

  begin

  for i in 4001..5000

  loop

  execute immediate

  'INSERT INTO T3 values(:x,:y)' USING i,'TJ';

  end loop;

  end;

  /

  exec proc1

  create or replace procedure proc1

  as

  begin

  for i in 5001..6000

  loop

  execute immediate

  'INSERT INTO T3 values(:x,:y)' USING i,'GZ';

  end loop;

  end;

  /

  exec proc1

  create or replace procedure proc1

  as

  begin

  for i in 6001..7000

  loop

  execute immediate

  'INSERT INTO T3 values(:x,:y)' USING i,'HB';

  end loop;

  end;

  /

  exec proc1

  create or replace procedure proc1

  as

  begin

  for i in 7001..8000

  loop

  execute immediate

  'INSERT INTO T3 values(:x,:y)' USING i,'SZ';

  end loop;

  end;

  /

  exec proc1

  create or replace procedure proc1

  as

  begin

  for i in 8001..10000

  loop

  execute immediate

  'INSERT INTO T3 values(:x,:y)' USING i,'AH';

  end loop;

  end;

  /

  exec proc1

  SQL> SET linesize 200

  SQL> select TABLE_NAME, TABLE_OWNER, PARTITION_NAME, SUBPARTITION_COUNT from dba_tab_partitions where table_name='T3';

  TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT

  ------------------------------ ------------------------------ ------------------------------ ------------------

  T3 HR P1 0

  T3 HR P2 0

  T3 HR P3 0

  T3 HR P_OTHERS 0

  实验一(SPLIT 分区)

  alter table t3 split partition p1 values ('JS') into

  (partition p1_1,partition p1_2);

  SQL> select TABLE_NAME, TABLE_OWNER, PARTITION_NAME, SUBPARTITION_COUNT from dba_tab_partitions where table_name='T3';

  TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT

  ------------------------------ ------------------------------ ------------------------------ ------------------

  T3 HR P1_1 0

  T3 HR P1_2 0

  T3 HR P2 0

  T3 HR P3 0

  T3 HR P_OTHERS 0

  实验二(merge 分区)

  alter table t3 merge partitions p1_1,p1_2 into partition p1;

  SQL> select TABLE_NAME, TABLE_OWNER, PARTITION_NAME, SUBPARTITION_COUNT from dba_tab_partitions where table_name='T3';

  TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT

  ------------------------------ ------------------------------ ------------------------------ ------------------

  T3 HR P1 0

  T3 HR P2 0

  T3 HR P3 0

  T3 HR P_OTHERS 0

  实验三、

  alter table t3 split partition p2 values ('BJ','TJ') into

  (partition p2_1,partition p2_2);

  SQL> select TABLE_NAME, TABLE_OWNER, PARTITION_NAME, SUBPARTITION_COUNT from dba_tab_partitions where table_name='T3';

  TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT

  ------------------------------ ------------------------------ ------------------------------ ------------------

  T3 HR P1 0

  T3 HR P2_1 0

  T3 HR P2_2 0

  T3 HR P3 0

  T3 HR P_OTHERS 0

  实验四、

  alter table t3 merge partitions p2_1,p2_2 into partition p2;

  SQL> select TABLE_NAME, TABLE_OWNER, PARTITION_NAME, SUBPARTITION_COUNT from dba_tab_partitions where table_name='T3';

  TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT

  ------------------------------ ------------------------------ ------------------------------ ------------------

  T3 HR P1 0

  T3 HR P2 0

  T3 HR P3 0

  T3 HR P_OTHERS 0

  实验五( 向分区某个分区里增加个分区列值)

  SQL> alter table t3 modify partition p3 add values('ZQ');

  Table altered.

  二,分区索引的相关实验

  实验六(创建索引分区)

  create index idx_t3 on t3(id)

  global partition by range(id)

  (

  partition p1 values less than (1000),

  partition p2 values less than (maxvalue)

  );

  drop index idx_3

  create index idx_t3 on t3(id)

  global partition by hash(id)

  partitions 4;

  create table tt2(id number,createdate date)

  partition by range(createdate)

  subpartition by hash(id) subpartitions 2

  (

  partition p1 values less than (to_date('2010-07-01','yyyy-mm-dd')),

  partition p2 values less than (to_date('2011-01-01','yyyy-mm-dd'))

  );

  create table tt4(id number,name varchar2(10))

  partition by range(name)

  (

  partition p1 values less than ('h'),

  partition p2 values less than ('o')

  );

  create index idx_tt4 on tt4(id) local;

  drop indexe idx_tt4 ;

  create index idx_tt4 on tt4(id)

  global partition by range(id)

  (

  partition p1 values less than (1000),

  partition p2 values less than (maxvalue)

  );

  SQL> SET LINESIZE 200

  SQL> select INDEX_OWNER, INDEX_NAME,PARTITION_NAME FROM dba_Ind_Partitions where index_name='IDX_TT4';

  INDEX_OWNER INDEX_NAME PARTITION_NAME

  ------------------------------ ------------------------------ ------------------------------

  HR IDX_TT4 P1

  HR IDX_TT4 P2

  alter index idx_tt4 split partition p2 at (2000) into

  (partition p3,partition p_max);

  SQL> select INDEX_OWNER, INDEX_NAME,PARTITION_NAME FROM dba_Ind_Partitions where index_name='IDX_TT4';

  INDEX_OWNER INDEX_NAME PARTITION_NAME

  ------------------------------ ------------------------------ ------------------------------

  HR IDX_TT4 P1

  HR IDX_TT4 P3

  HR IDX_TT4 P_MAX

  三,分区表交换的相关实验

  Exchange partition提供了一种方式,让你在表与表或分区与分区之间迁移数据,注意不是将表转换成分区或非分区的形式,而仅只是迁移表中数据(互相迁移),

  由于其号称是采用了更改数据字典的方式,因此效率最高(几乎不涉及io操作)。Exchange partition适用于所有分区格式,你可以将数据从分区表迁移到非分区表,

  也可以从非分区表迁移至分区表,或者从hash partition到range partition诸如此类。

  其语法:alter table tbname1 exchange partition/subpartition ptname with table tbname2;

  注意:在将未分区表的数据迁移到分区表中时,可能出现ora-14099的错误,虽然可以用without validation去解决,但是此时进入分区表的数据可能不符合分区规

  则。所以without validation一定要慎用。

  a,涉及交换的两表之间表结构必须一致,除非附加with validation子句;

  b,如果是从非分区表向分区表做交换,非分区表中的数据必须符合分区表中指定分区的规则,除非附加without validation子句;

  c,如果从分区表向分区表做交换,被交换的分区的数据必须符合分区规则,除非附加without validation子句;

  d,Global索引或涉及到数据改动了的global索引分区会被置为unusable,除非附加update indexes子句。

  注意:

  一旦附加了without validation子句,则表示不再验证数据有效性,因此指定该子句时务必慎重。

  创建一个交换分区的普通heap表

  SQL> create table exchange_t3(id number,city varchar2(10));

  Table created.

  SQL> select distinct city from t3 partition (p2);

  CITY

  ----------

  TJ

  BJ

  HB

  查看下P2分区有records

  SQL> select count(*) from t3 partition (p2);

  COUNT(*)

  ----------

  3000

  下面是分区表和普通HEAP表交换

  alter table t3

  exchange partition p2

  with table exchange_t3

  including indexes

  without validation;

  验证下数据,和上面的P2分区数据一致。

  SQL> select count(*) from exchange_t3;

  COUNT(*)

  ----------

  3000

  SQL> select distinct city from exchange_t3;

  CITY

  ----------

  TJ

  BJ

  HB

  四,一个实际应用的例子的相关实验

  创建一个分区表,只保留最近2年的财务数据。

  create table ware(wareyear varchar2(4),id number)

  partition by range (wareyear)

  (

  partition p_2005 values less than('2006'),

  partition p_2006 values less than('2007'),

  partition p_max values less than(maxvalue)

  );

  创建索引

  create index idx_ware_id on ware(id)

  global partition by range(id)

  (

  partition p_id_10000 values less than(10000),

  partition p_id_max values less than(maxvalue)

  );

  create index idx_ware_wareyear on ware(wareyear) local;

  插入测试数据

  insert into ware select '2005',object_id from dba_objects;

  insert into ware select '2006',object_id from dba_objects;

  commit;

  年终,归档最早的数据,并加入新财年的数据

  create table ware_2007(wareyear varchar2(4),id number);

  create index idx_ware_2007 on ware_2007(wareyear);

  insert into ware_2007 select '2007',object_id from dba_objects;

  commit;

  alter table ware split partition p_max

  at ('2008') into (partition p_2007, partition p_max);

  将p_2007分区放入ware_2007表里

  alter table ware exchange partition p_2007

  with table ware_2007

  including indexes

  without validation;

  create table ware_2005(wareyear varchar2(4),id number);

  create index idx_ware_2005 on ware_2005(wareyear);

  alter table ware exchange partition p_2005

  with table ware_2005

  including indexes

  without validation;

  删除p_2005分区

  alter table ware drop partition p_2005;

  导出做归档

  [oracle@even admin]$ exp hr/hr@test file=/home/oracle/ware_2005.dmp tables=ware_2005 compress=n

  Export: Release 10.2.0.1.0 - Production on Fri Jan 18 05:10:42 2013

  Copyright (c) 1982, 2005, Oracle. All rights reserved.

  Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production

  With the Partitioning, Oracle Label Security, OLAP and Data Mining options

  Export done in US7ASCII character set and AL16UTF16 NCHAR character set

  server uses AL32UTF8 character set (possible charset conversion)

  About to export specified tables via Conventional Path ...

  . . exporting table WARE_2005 50439 rows exported

  Export terminated successfully without warnings.

  然后删除表

  drop table ware_2005;

  五,表和索引的维护的常见SQL语句及注意事项

  对于分区索引,不能整体进行重建,只能对单个分区进行重建(也就是物理存在的分区)。语法如下:

  Alter index idx_name rebuild partition index_partition_name [online nologging]

  Alter Index IndexName Rebuild Partition P_Name;

  有子分区的本地索引,不能重建某分区,只能对每个子分区进行重建

  Alter Index Index_Name Rebuild subPartition P_Sub_Name;

  脚本,重建所有unUsable的索引

  Select 'alter index ' || Index_Name ||' rebuild;' From User_Indexes Where Status ='UNUSABLE' union

  Select 'alter index ' || Index_Name ||' rebuild Partition '||Partition_Name ||';' From User_Ind_Partitions Where Status ='UNUSABLE' union

  Select 'alter index ' || Index_Name ||' rebuild subPartition '||subPartition_Name ||';' From User_Ind_subPartitions Where Status ='UNUSABLE';

  add parttion

  Alter Table TestTab1 Add Partition P1 Values Less Than (20120801);

  1, 如果有子分区,且定义了子分区模板,所有的子分区会自动添加

  2, 新加分区后,该区没有统计信息,全是空,如果表级不是global_satus,则表级的统计信息也会空

  3, 新加分区后,如果表级统计是global_satus,还会出现out of range的问题(CBO估算的选择率很低)

  4, 解决2,3问题的方法是:copy_table_stats

  exec dbms_stats.copy_table_stats(user, tabname => 'TEST_TAB1', srcpartname =>'P_20120801', dstpartname => 'P_20100208');

  tuncate and drop partition

  truncate和drop可对有子分区的分区进行

  ALTER TABLE TEST truncate Partition P_20120801;

  ALTER TABLE TEST Drop Partition P_20120801;

  它们会导致globl index的某些分区不可用,必须这样做

  ALTER TABLE TEST truncate Partition P_20120801 update indexes;

  ALTER TABLE TEST truncate Partition P_20120801update global indexes;

  ALTER TABLE TEST Drop Partition P_20120801 update indexes;

  ALTER TABLE TEST Drop Partition P_20120801 update global indexes;

  move partition

  有子分区的分区不能move,只能move每个子分区(也就是物理分区)

  Alter Table TEST Move Partition P_20120801;

  由于rowid变了,会导致所有相关索引unusable,必须这样做

  Alter Table TEST Move subPartition P_20100730_P1 update indexes;

  Alter Table TEST Move subPartition P_20100730_P2 update global indexes; --Local Index没有更新

  split partion

  语法:

  alter table <table_name>

  split partition <partition_name> at (<value>)

  into (partition <partition_name>, partition <partition_name>)

  [update [global] indexes];

  1 可以对有子分区的分区进行,自动split子分区

  2 由于rowid变了,新分区和global index都变为unusable

  alter table t3 merge partitions p2_1,p2_2 into partition p2;

  合并range分区

  ALTER TABLE Test_Tab1

  Merge Partitions P_20100715, P_20100731 Into Partition P_20100730

  [Update [global] Indexes];

  1. 该分区有子分区

  2. 有子分区,也可以单独合并子分区merge subpartition

  可以通过下面的视图获取分区的信息

  dba_segments

  dba_part_key_columns

  dba_tables

  dba_tab_partitions

  dba_indexes

  dba_ind_partitions
分享到:
本文"Oracle分区之四:分区维护和管理"由远航站长收集整理而来,仅供大家学习与参考使用。更多网站制作教程尽在远航站长站。
顶一下
(0)
0%
踩一下
(0)
0%
[点击 次] [返回上一页] [打印]
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
关于本站 - 联系我们 - 广告合作 - 网站声明 - 友情连接- 网站地图 - 站点地图 - 返回顶部
Copyright © 2007-2013 www.yhzhan.com(远航站长). All Rights Reserved .
远航站长:为中小站长提供最佳的学习与交流平台,提供网页制作与网站编程等各类网站制作教程.
官方QQ:445490277 网站群:26680406 网站备案号:豫ICP备07500620号-4