网站建设资讯

NEWS

网站建设资讯

oracle如何改分区 oracle如何加分区

如何将Oracle数据库的普通表转换成分区表

常用两种方法:

成都网络公司-成都网站建设公司成都创新互联十多年经验成就非凡,专业从事成都做网站、成都网站设计、成都外贸网站建设,成都网页设计,成都网页制作,软文发稿广告投放等。十多年来已成功提供全面的成都网站建设方案,打造行业特色的成都网站建设案例,建站热线:13518219792,我们期待您的来电!

一种是使用create table as select方式创建一个分区表,然后将普通表重命名,然后对新的分区表创建所需索引,重命名等。

另外一种是在线重定义方式,调用DBMS_REDEFINITION这个包来实现,详情可百度学习下。

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

个人推荐第一种,稳妥,速度也不错,嘿嘿!

Oracle创建分区表操作

1、创建语句

create table p(id number)

partition by range(id)

(partition p1 values less than(100) tablespace t1,

partition p2 values less than(200) tablespace t2,

partition p3 values less than(300) tablespace t3);

2、添加分区

alter table p add partition p4 values less than (400) tablespace t4;

3、清除分区数据

alter table p trunc partition p1;

4、删除分区

alter table p drop partition p1;

Oracle数据库分区表操作方法

在大型的企业应用或企业级的数据库应用中 要处理的数据量通常可以达到几十到几百GB 有的甚至可以到TB级 虽然存储介质和数据处理技术的发展也很快 但是仍然不能满足用户的需求 为了使用户的大量的数据在读写操作和查询中速度更快 Oracle提供了对表和索引进行分区的技术 以改善大型应用系统的性能

使用分区的优点

·增强可用性 如果表的某个分区出现故障 表在其他分区的数据仍然可用

·维护方便 如果表的某个分区出现故障 需要修复数据 只修复该分区即可

·均衡I/O 可以把不同的分区映射到磁盘以平衡I/O 改善整个系统性能

·改善查询性能 对分区对象的查询可以仅搜索自己关心的分区 提高检索速度

Oracle数据库提供对表或索引的分区方法有三种

·范围分区

·Hash分区(散列分区)

·复合分区

下面将以实例的方式分别对这三种分区方法来说明分区表的使用 为了测试方便 我们先建三个表空间

以下为引用的内容

create tablespace dinya_space

datafile /test/demo/oracle/demodata/dinya dnf size M

create tablespace dinya_space

datafile /test/demo/oracle/demodata/dinya dnf size M

create tablespace dinya_space

datafile /test/demo/oracle/demodata/dinya dnf size M

分区表的创建

范围分区

范围分区就是对数据表中的某个值的范围进行分区 根据某个值的范围 决定将该数据存储在哪个分区上 如根据序号分区 根据业务记录的创建日期进行分区等

需求描述 有一个物料交易表 表名 material_transactions 该表将来可能有千万级的数据记录数 要求在建该表的时候使用分区表 这时候我们可以使用序号分区三个区 每个区中预计存储三千万的数据 也可以使用日期分区 如每五年的数据存储在一个分区上

根据交易记录的序号分区建表 以下为引用的内容

SQL create table dinya_test

(

transaction_id number primary key

item_id number( ) not null

item_description varchar ( )

transaction_date date not null

)

partition by range (transaction_id)

(

partition part_ values less than( ) tablespace dinya_space

partition part_ values less than( ) tablespace dinya_space

partition part_ values less than(maxvalue) tablespace dinya_space

);

Table created

建表成功 根据交易的序号 交易ID在三千万以下的记录将存储在第一个表空间dinya_space 中 分区名为:par_ 在三千万到六千万之间的记录存储在第二个表空间

dinya_space 中 分区名为 par_ 而交易ID在六千万以上的记录存储在第三个表空间dinya_space 中 分区名为par_

根据交易日期分区建表

以下为引用的内容

SQL create table dinya_test

(

transaction_id number primary key

item_id number( ) not null

item_description varchar ( )

transaction_date date not null

)

partition by range (transaction_date)

(

partition part_ values less than(to_date( yyyy mm dd ))

tablespace dinya_space

partition part_ values less than(to_date( yyyy mm dd ))

tablespace dinya_space

partition part_ values less than(maxvalue) tablespace dinya_space

);

Table created

这样我们就分别建了以交易序号和交易日期来分区的分区表 每次插入数据的时候 系统将根据指定的字段的值来自动将记录存储到制定的分区(表空间)中

当然 我们还可以根据需求 使用两个字段的范围分布来分区 如partition

by range ( transaction_id transaction_date)

分区条件中的值也做相应的改变 请读者自行测试

Hash分区(散列分区)

散列分区为通过指定分区编号来均匀分布数据的一种分区类型 因为通过在I/O设备上进行散列分区 使得这些分区大小一致 如将物料交易表的数据根据交易ID散列地存放在指定的三个表空间中

以下为引用的内容

SQL create table dinya_test

(

transaction_id number primary key

item_id number( ) not null

item_description varchar ( )

transaction_date date

)

partition by hash(transaction_id)

(

partition part_ tablespace dinya_space

partition part_ tablespace dinya_space

partition part_ tablespace dinya_space

);

Table created

建表成功 此时插入数据 系统将按transaction_id将记录散列地插入三个分区中 这里也就是三个不同的表空间中

复合分区

有时候我们需要根据范围分区后 每个分区内的数据再散列地分布在几个表空间中 这样我们就要使用复合分区 复合分区是先使用范围分区 然后在每个分区内再使用散列分区的一种分区方法 如将物料交易的记录按时间分区 然后每个分区中的数据分三个子分区 将数据散列地存储在三个指定的表空间中

以下为引用的内容

SQL create table dinya_test

(

transaction_id number primary key

item_id number( ) not null

item_description varchar ( )

transaction_date date

)

partition by range(transaction_date)subpartition by hash(transaction_id)

subpartitions store in (dinya_space dinya_space dinya_space )

(

partition part_ values less than(to_date( yyyy mm dd ))

partition part_ values less than(to_date( yyyy mm dd ))

partition part_ values less than(maxvalue)

);

Table created

该例中 先是根据交易日期进行范围分区 然后根据交易的ID将记录散列地存储在三个表空间中

分区表操作

以上了解了三种分区表的建表方法 下面将使用实际的数据并针对按日期的范围分区来测试分区表的数据记录的操作

插入记录

以下为引用的内容

SQL insert into dinya_test values( BOOKS sysdate);

row created

SQL insert into dinya_test values( BOOKS sysdate+ );

row created

SQL insert into dinya_test values( BOOKS to_date( yyyy mm dd ));

row created

SQL insert into dinya_test values( BOOKS to_date( yyyy mm dd ));

row created

SQL insert into dinya_test values( BOOKS to_date( yyyy mm dd ));

row created

SQL insert into dinya_test values( BOOKS to_date( yyyy mm dd ));

row created

SQL mit;

Commit plete

SQL

按上面的建表结果 年前的数据将存储在第一个分区part_ 上 而 年到 年的交易数据将存储在第二个分区part_ 上 年以后的记录存储在第三个分区part_ 上

查询分区表记录 以下为引用的内容

SQL select * from dinya_test partition(part_ );

TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE

BOOKS : :

BOOKS : :

SQL

SQL select * from dinya_test partition(part_ );

TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE

BOOKS

BOOKS

SQL

SQL select * from dinya_test partition(part_ );

TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE

BOOKS

BOOKS

SQL

从查询的结果可以看出 插入的数据已经根据交易时间范围存储在不同的分区中 这里是指定了分区的查询 当然也可以不指定分区 直接执行select * from dinya_test查询全部记录

在也检索的数据量很大的时候 指定分区会大大提高检索速度

更新分区表的记录

以下为引用的内容

SQL update dinya_test partition(part_ ) t set em_description= DESK where

t transaction_id= ;

row updated

SQL mit;

Commit plete

SQL

这里将第一个分区中的交易ID= 的记录中的item_description字段更新为 DESK 可以看到已经成功更新了一条记录 但是当更新的时候指定了分区 而根据查询的记录不在该分区中时 将不会更新数据 请看下面的例子 以下为引用的内容

SQL update dinya_test partition(part_ ) t set em_description= DESK where

t transaction_id= ;

rows updated

SQL mit;

Commit plete

SQL

指定了在第一个分区中更新记录 但是条件中限制交易ID为 而查询全表 交易ID为 的记录在第三个分区中 这样该条语句将不会更新记录

删除分区表记录

以下为引用的内容

SQL delete from dinya_test partition(part_ ) t where t transaction_id= ;

row deleted

SQL mit;

Commit plete

SQL

上面例子删除了第二个分区part_ 中的交易记录ID为 的一条记录 和更新数据相同 如果指定了分区 而条件中的数据又不在该分区中时 将不会删除任何数据

分区表索引的使用

分区表和一般表一样可以建立索引 分区表可以创建局部索引和全局索引 当分区中出现许多事务并且要保证所有分区中的数据记录的唯一性时采用全局索引

局部索引分区的建立

以下为引用的内容

SQL create index dinya_idx_t on dinya_test(item_id)

local

(

partition idx_ tablespace dinya_space

partition idx_ tablespace dinya_space

partition idx_ tablespace dinya_space

);

Index created

SQL

看查询的执行计划 从下面的执行计划可以看出 系统已经使用了索引

以下为引用的内容

SQL select * from dinya_test partition(part_ ) t where em_id= ;

Execution Plan

SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes= )

TABLE ACCESS (BY LOCAL INDEX ROWID) OF DINYA_TEST (Cost=

Card= Bytes= )

INDEX (RANGE SCAN) OF DINYA_IDX_T (NON UNIQUE) (Cost=

Card= )

Statistics

recursive calls

db block gets

consistent gets

physical reads

redo size

bytes sent via SQL*Net to client

bytes received via SQL*Net from client

SQL*Net roundtrips to/from client

sorts (memory)

sorts (disk)

rows processed

SQL

全局索引分区的建立

全局索引建立时global 子句允许指定索引的范围值 这个范围值为索引字段的范围值

以下为引用的内容

SQL create index dinya_idx_t on dinya_test(item_id)

global partition by range(item_id)

(

partition idx_ values less than ( ) tablespace dinya_space

partition idx_ values less than ( ) tablespace dinya_space

partition idx_ values less than (maxvalue) tablespace dinya_space

);

Index created

SQL

本例中对表的item_id字段建立索引分区 当然也可以不指定索引分区名直接对整个表建立索引 如

以下为引用的内容

SQL create index dinya_idx_t on dinya_test(item_id);

Index created

SQL

同样的 对全局索引根据执行计划可以看出索引已经可以使用

以下为引用的内容

SQL select * from dinya_test t where em_id= ;

Execution Plan

SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes= )

TABLE ACCESS (BY GLOBAL INDEX ROWID) OF DINYA_TEST (Cost

= Card= Bytes= )

INDEX (RANGE SCAN) OF DINYA_IDX_T (NON UNIQUE) (Cost=

Card= )

Statistics

recursive calls

db block gets

consistent gets

physical reads

redo size

bytes sent via SQL*Net to client

bytes received via SQL*Net from client

SQL*Net roundtrips to/from client

sorts (memory)

sorts (disk)

rows processed

SQL

分区表的维护

了解了分区表的建立 索引的建立 表和索引的使用后 在应用的还要经常对分区进行维护和管理 日常维护和管理的内容包括 增加一个分区 合并一个分区及删除分区等等 下面以范围分区为例说明增加 合并 删除分区的一般操作

增加一个分区:

以下为引用的内容

SQL alter table dinya_test

add partition part_ values less than(to_date( yyyy mm dd ))

tablespace dinya_spa

ce ;

Table altered

SQL

增加一个分区的时候 增加的分区的条件必须大于现有分区的最大值 否则系统将提示ORA partition bound must collate higher than that of the last partition 错误

合并一个分区

以下为引用的内容

SQL alter table dinya_test merge partitions part_ part_ into partition part_ ;

Table altered

SQL

在本例中将原有的表的part_ 分区和part_ 分区进行了合并 合并后的分区为part_ 如果在合并的时候把合并后的分区定为part_ 的时候 系统将提示ORA cannot reuse lower bound partition as resulting partition 错误

删除分区

以下为引用的内容

SQL alter table dinya_test drop partition part_ ;

Table altered

SQL

删除分区表的一个分区后 查询该表的数据时显示 该分区中的数据已全部丢失 所以执行删除分区动作时要慎重 确保先备份数据后再执行 或将分区合并

总结

lishixinzhi/Article/program/Oracle/201311/17329

oracle怎么更改分区关键字

默认情况下,oracle的分区表对于分区字段是不允许进行update操作的,如果有对分区字段行进update,就会报错——ORA-14402: 更新分区关键字列将导致分区的更改。但是可以通过打开表的row movement属性来允许对分区字段的update操作。

例:创建分区表test_part进行实验

create table TEST_PART

(

A1 NUMBERnot null,

A2 DATE not null,

A3 VARCHAR2(6) not null,

A4 DATE not null,

A5 NUMBER not null,

)

partition by range (A1)

(

partition P1 values less than (1000),

partition P2 values less than (2000),

partition P3 values less than (3000),

partition P4 values less than (4000),

partition P5 values less than (5000),

partition P6 values less than (MAXVALUE)

);

插入如下的数据

SQL select * from test_part;

A1 A2 A3 A4 A5

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

123 2006-06-30 123456 2006-06-30 123

456 2006-06-30 asdfgh 2006-06-30 456

1 2006-06-30 234123 2006-06-30 1

2 2006-06-30 234234 2006-06-30 2

1234 2006-06-30 456789 2006-06-30 1234

1111 2006-06-30 ewrqwe 2006-06-30 1111

2222 2006-06-30 fdafda 2006-06-30 2222

3333 2006-06-30 342342 2006-06-30 3333

5678 2006-06-30 qwerty 2006-06-30 5678

9 rows selected

分区P1、P2的数据分别为:

SQL select rowid,t.* from test_part partition(p1) t;

ROWID A1 A2 A3 A4 A5

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

AAAGLoAAGAAAtsEAAB 456 2006-06-30 asdfgh 2006-06-30 456

AAAGLoAAGAAAtsEAAC 1 2006-06-30 234123 2006-06-30 1

AAAGLoAAGAAAtsEAAD 2 2006-06-30 234234 2006-06-30 2

AAAGLoAAGAAAtsEAAE 123 2006-06-30 123456 2006-06-30 123

SQL select rowid,t.* from test_part partition(p2) t;

ROWID A1 A2 A3 A4 A5

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

AAAGLwAAGAAA+8MAAC 1234 2006-06-30 456789 2006-06-30 1234

AAAGLwAAGAAA+8MAAD 1111 2006-06-30 ewrqwe 2006-06-30 1111

直接update提示错误

SQL update test_part set a1=1123 where a1=123;

update test_part set a1=1123 where a1=123

ORA-14402: 更新分区关键字列将导致分区的更改

打开row movement属性

SQL alter table test_part enable row movement;

Table altered

再次执行update操作

SQL update test_part set a1=1123 where a1=123;

1 row updated

执行是成功的并迁移到分区P2上了,且这时候rowid也发生了变化

SQL select rowid,t.* from test_part partition(p2) t;

ROWID A1 A2 A3 A4 A5

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

AAAGLwAAGAAA+8MAAC 1234 2006-06-30 456789 2006-06-30 1234

AAAGLwAAGAAA+8MAAD 1111 2006-06-30 ewrqwe 2006-06-30 1111

AAAGLwAAGAAA+8PAAB 1123 2006-06-30 123456 2006-06-30 123

SQL

enable row movement可以允许数据段的压缩、update分区字段的数据(跨分区的)

oracle11g自动分区

在Oracle10g中,没有定义间隔分区,只能通过范围分区实现间隔分区功能,如果要实现自动创建分区,只能通过创建JOB或者scheduler来实现;而在11g中,Oracle直接提供了间隔分区功能,大大简化了间隔分区的实现。

----注:oracle11g虽然可以自动分区,但是分区的名字不能自定义,对于需要定时删除分区时没法处理,不如通过时间范围来手工分区。详见

create table HIP_LOG_NODE_Part

(

ID                   VARCHAR2(32)         not null,

RECORD_TIME          DATE

)tablespace TB_HIP_LOG_NODE

PARTITION BY RANGE (RECORD_TIME) interval (numtoyminterval(1, 'month'))

STORE IN (TB_HIP_LOG_NODE)

(

partition hip_log_node_partition values less than (to_date('2019-08-01 00:00','yyyy-MM-dd HH24:mi')) tablespace TB_HIP_LOG_NODE

);

1、Oracle11g有间隔分区功能,对于使用Range分区的可以按年,月,日来自动生成分区。

2、2019-08-01前的数据(包含8月份的数据)会放入hip_log_node_partition 分区,8月1日后的数据每月只要有数据,就会自动创建一个分区。也就是从9月开始,开始新建分区。

3、interval函数--将数值按标准换算为日期

numtodsinterval、numtodsinterval函数,将数字转成年月,时分秒

详见:

4、查看表分区 select table_name,partition_name from user_tab_partitions where table_name='INTERVAL_SALES';

5、插入数据再次查看分区,详见:

6、修改分区、合并分区、拆分分区,详见 :

7、创建索引(分区索引、全局索引) :

非分区字段创建主键,则创建主键local索引时必须加上分区字段

ALTER TABLE TEST ADD CONSTRAINT PK_TEST PRIMARY KEY (主键字段,分区字段) USING INDEX LOCAL;

8、oracle 10g创建表分区

9、删除

1.不保留,直接删除:

alter table table_name drop/truncate partition partition_name;

具体用drop还是truncate,得你自己衡量,drop的话原来的分区和数据直接就没有了,truncate的话,只是数据没有了,分区还在。

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

一 分区表的相关实验 创建一个列表分区表 create table t (id number city varchar ( )) partition by list(city) ( partition p values ( SH JS ZJ ) partition p values ( BJ TJ HB ) partition p values ( GZ SZ ) partition p_others values (default) ); create or replace procedure proc as begin for i in loop execute immediate INSERT INTO T values(:x :y) USING i SH ; end loop; end; / exec proc create or replace procedure proc as begin for i in loop execute immediate INSERT INTO T values(:x :y) USING i JS ; end loop; end; / exec proc create or replace procedure proc as begin for i in loop execute immediate INSERT INTO T values(:x :y) USING i ZJ ; end loop; end; / exec proc create or replace procedure proc as begin for i in loop execute immediate INSERT INTO T values(:x :y) USING i BJ ; end loop; end; / exec proc create or replace procedure proc as begin for i in loop execute immediate INSERT INTO T values(:x :y) USING i TJ ; end loop; end; / exec proc create or replace procedure proc as begin for i in loop execute immediate INSERT INTO T values(:x :y) USING i GZ ; end loop; end; / exec proc create or replace procedure proc as begin for i in loop execute immediate INSERT INTO T values(:x :y) USING i HB ; end loop; end; / exec proc create or replace procedure proc as begin for i in loop execute immediate INSERT INTO T values(:x :y) USING i SZ ; end loop; end; / exec proc create or replace procedure proc as begin for i in loop execute immediate INSERT INTO T values(:x :y) USING i AH ; end loop; end; / exec proc SQL SET linesize SQL select TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT from dba_tab_partitions where table_name= T ; TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT T HR P T HR P T HR P T HR P_OTHERS

实验一(SPLIT 分区) alter table t split partition p values ( JS ) into (partition p _ partition p _ ); SQL select TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT from dba_tab_partitions where table_name= T ; TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT T HR P _ T HR P _ T HR P T HR P T HR P_OTHERS

实验二(merge 分区) alter table t merge partitions p _ p _ into partition p ; SQL select TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT from dba_tab_partitions where table_name= T ; TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT T HR P T HR P T HR P T HR P_OTHERS 实验三 alter table t split partition p values ( BJ TJ ) into (partition p _ partition p _ ); SQL select TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT from dba_tab_partitions where table_name= T ; TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT T HR P T HR P _ T HR P _ T HR P T HR P_OTHERS

实验四 alter table t merge partitions p _ p _ into partition p ; SQL select TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT from dba_tab_partitions where table_name= T ; TABLE_NAME TABLE_OWNER PARTITION_NAME SUBPARTITION_COUNT T HR P T HR P T HR P T HR P_OTHERS 实验五( 向分区某个分区里增加个分区列值) SQL alter table t modify partition p add values( ZQ ); Table altered 二 分区索引的相关实验 实验六(创建索引分区) create index idx_t on t (id) global partition by range(id) ( partition p values less than ( ) partition p values less than (maxvalue) ); drop index idx_ create index idx_t on t (id) global partition by hash(id) partitions ; create table tt (id number createdate date) partition by range(createdate) subpartition by hash(id) subpartitions ( partition p values less than (to_date( yyyy mm dd )) partition p values less than (to_date( yyyy mm dd )) ); create table tt (id number name varchar ( )) partition by range(name) ( partition p values less than ( h ) partition p values less than ( o ) ); create index idx_tt on tt (id) local; drop indexe idx_tt ; create index idx_tt on tt (id) global partition by range(id) ( partition p values less than ( ) partition p values less than (maxvalue) ); SQL SET LINESIZE SQL select INDEX_OWNER INDEX_NAME PARTITION_NAME FROM dba_Ind_Partitions where index_name= IDX_TT ; INDEX_OWNER INDEX_NAME PARTITION_NAME HR IDX_TT P HR IDX_TT P

alter index idx_tt split partition p at ( ) into (partition p partition p_max); SQL select INDEX_OWNER INDEX_NAME PARTITION_NAME FROM dba_Ind_Partitions where index_name= IDX_TT ; INDEX_OWNER INDEX_NAME PARTITION_NAME HR IDX_TT P HR IDX_TT P HR IDX_TT P_MAX

三 分区表交换的相关实验 Exchange partition提供了一种方式 让你在表与表或分区与分区之间迁移数据 注意不是将表转换成分区或非分区的形式 而仅只是迁移表中数据(互相迁移) 由于其号称是采用了更改数据字典的方式 因此效率最高(几乎不涉及io操作) Exchange partition适用于所有分区格式 你可以将数据从分区表迁移到非分区表 也可以从非分区表迁移至分区表 或者从hash partition到range partition诸如此类 其语法 alter table tbname exchange partition/subpartition ptname with table tbname ; 注意 在将未分区表的数据迁移到分区表中时 可能出现ora 的错误 虽然可以用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_t (id number city varchar ( )); Table created SQL select distinct city from t partition (p ); CITY TJ BJ HB 查看下P 分区有records SQL select count(*) from t partition (p ); COUNT(*) 下面是分区表和普通HEAP表交换 alter table t exchange partition p with table exchange_t including indexes without validation; 验证下数据 和上面的P 分区数据一致 SQL select count(*) from exchange_t ; COUNT(*) SQL select distinct city from exchange_t ; CITY TJ BJ HB 四 一个实际应用的例子的相关实验 创建一个分区表 只保留最近 年的财务数据 create table ware(wareyear varchar ( ) id number) partition by range (wareyear) ( partition p_ values less than( ) partition p_ values less than( ) partition p_max values less than(maxvalue) ); 创建索引 create index idx_ware_id on ware(id) global partition by range(id) ( partition p_id_ values less than( ) partition p_id_max values less than(maxvalue) ); create index idx_ware_wareyear on ware(wareyear) local; 插入测试数据 insert into ware select object_id from dba_objects; insert into ware select object_id from dba_objects; mit; 年终 归档最早的数据 并加入新财年的数据 create table ware_ (wareyear varchar ( ) id number); create index idx_ware_ on ware_ (wareyear); insert into ware_ select object_id from dba_objects; mit; alter table ware split partition p_max at ( ) into (partition p_ partition p_max); 将p_ 分区放入ware_ 表里 alter table ware exchange partition p_ with table ware_ including indexes without validation; create table ware_ (wareyear varchar ( ) id number); create index idx_ware_ on ware_ (wareyear); alter table ware exchange partition p_ with table ware_ including indexes without validation; 删除p_ 分区 alter table ware drop partition p_ ; 导出做归档 [oracle@even admin]$ exp hr/hr@test file=/home/oracle/ware_ dmp tables=ware_ press=n Export: Release Production on Fri Jan : : Copyright (c) Oracle All rights reserved

Connected to: Oracle Database g Enterprise Edition Release Production With the Partitioning Oracle Label Security OLAP and Data Mining options Export done in US ASCII character set and AL UTF NCHAR character set server uses AL UTF character set (possible charset conversion) About to export specified tables via Conventional Path exporting table WARE_ rows exported Export terminated successfully without warnings 然后删除表 drop table ware_ ;

五 表和索引的维护的常见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 TestTab Add Partition P Values Less Than ( ); 如果有子分区 且定义了子分区模板 所有的子分区会自动添加 新加分区后 该区没有统计信息 全是空 如果表级不是global_satus 则表级的统计信息也会空 新加分区后 如果表级统计是global_satus 还会出现out of range的问题(CBO估算的选择率很低) 解决 问题的方法是 copy_table_stats exec dbms_stats copy_table_stats(user tabname = TEST_TAB srcpartname = P_ dstpartname = P_ );

tuncate and drop partition truncate和drop可对有子分区的分区进行 ALTER TABLE TEST truncate Partition P_ ; ALTER TABLE TEST Drop Partition P_ ; 它们会导致globl index的某些分区不可用 必须这样做 ALTER TABLE TEST truncate Partition P_ update indexes; ALTER TABLE TEST truncate Partition P_ update global indexes; ALTER TABLE TEST Drop Partition P_ update indexes; ALTER TABLE TEST Drop Partition P_ update global indexes;

move partition 有子分区的分区不能move 只能move每个子分区(也就是物理分区) Alter Table TEST Move Partition P_ ; 由于rowid变了 会导致所有相关索引unusable 必须这样做 Alter Table TEST Move subPartition P_ _P update indexes; Alter Table TEST Move subPartition P_ _P 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]; 可以对有子分区的分区进行 自动split子分区 由于rowid变了 新分区和global index都变为unusable alter table t merge partitions p _ p _ into partition p ; 合并range分区 ALTER TABLE Test_Tab Merge Partitions P_ P_ Into Partition P_ [Update [global] Indexes]; 该分区有子分区 有子分区 也可以单独合并子分区merge subpartition

lishixinzhi/Article/program/Oracle/201311/19037


新闻名称:oracle如何改分区 oracle如何加分区
浏览地址:http://njwzjz.com/article/hpoooo.html