一年又一年,又到年底了,对于数据库的分区表需要检查一下,有无最大分区,次分区是否需要追加分区,如果程序不是自动追加分区的话,那么年中结算的时候,就会报错。
1、oracle分区主要有五种类型
(1)RANGE分区 范围分区
(2)LIST分区 列表分区
(3)HASH分区 哈希分区
(4)Range-Hash 复合分区
(5)Range-List 复合分区
2、使用分区表的好处
1)由于将数据分散到各个分区中,减少了数据损坏的可能性;
2)可以对单独的分区进行备份和恢复;
3)可以将分区映射到不同的物理磁盘上,来分散IO;
4)提高可管理性、可用性和性能;
5)适用于大型OLAP系统。
3、检查当期分区以及分区中的High_Value值
SQL> col table_name
for A13
SQL> col
partition_name for
A12
SQL> col
partitioning_type for
a6
SQL> col
subpartitioning_type for
a6
SQL> col high_value
for a80
SQL> SELECT table_name,
partition_name,high_value,partitioning_type,subpartitioning_type
2
FROM (SELECT a.table_name,
a.partition_name,high_value,b.partitioning_type,b.subpartitioning_type,
3
rank() over(PARTITION
BY a.table_name ORDER BY a.partition_name DESC)
rankid
4 FROM dba_tab_partitions a,dba_part_tables
b
5 where a.table_name = 'PART_TB_NAME'
6
and a.table_name = b.table_name)
7 WHERE rankid <= 3;
TABLE_NAME PARTITION_NA HIGH_VALUE PARTIT
SUBPAR
------------- ------------
--------------------------------------------------------------------------------
------ ------
PART_TB_NAME PMAX MAXVALUE RANGE
NONE
PART_TB_NAME P20131130 TO_DATE(' 2013-12-01
00:00:00', 'SYYYY-MM-DD
HH24:MI:SS',
'NLS_CALENDAR=GREGORIA RANGE NONE
PART_TB_NAME P20131031 TO_DATE(' 2013-11-01 00:00:00',
'SYYYY-MM-DD HH24:MI:SS',
'NLS_CALENDAR=GREGORIA
RANGE NONE
以上SQL取分区表的前三个分区,同统计相关表的相关信息。
4、APPEND分区
首先查询最大分区是否已经含有数据:没有数据,就可以直接删除,然后再重新创建最大分区。
SELECT COUNT(1) FROM PART_TB_NAME
PARTITION(pmax);--0
ALTER TABLE PART_TB_NAME DROP PARTITION pmax;
ALTER tABLE PART_TB_NAME ADD PARTITION P20140131 values less than (TO_DATE('2014-02-01
00:00:00', 'SYYYY-MM-DD
HH24:MI:SS',
'NLS_CALENDAR=GREGORIAN'))
TABLESAPCE TESTDATA;
ALTER tABLE PART_TB_NAME ADD PARTITION P20140228 values less than (TO_DATE('2014-03-01
00:00:00', 'SYYYY-MM-DD
HH24:MI:SS',
'NLS_CALENDAR=GREGORIAN'))
TABLESAPCE TESTDATA;
ALTER tABLE PART_TB_NAME ADD PARTITION P20140331 values less than (TO_DATE('2014-04-01
00:00:00', 'SYYYY-MM-DD
HH24:MI:SS',
'NLS_CALENDAR=GREGORIAN')) TABLESAPCE TESTDATA;ALTER
TABLE PART_TB_NAME ADD PARTITION pmax
values less than (maxvalue) TABLESAPCE TESTDATA;
--#新建最大分区
5、SPLIT分区
如果最大分区里有数据,需要将最大分区里的数据剥离出去,然后再重新追加分区。
select COUNT(1) from PART_TB_NAME partition(PMAX);
--3
select COUNT(1) from PART_TB_NAME partition(P20131231);
--2
alter table PART_TB_NAME split partition pmax
at(to_date('2013-12-31','yyyy-mm-dd')) into (partition P20131231,partition pmax);
--将分区键值小于20131231的数据split到P20131231分区中。
alter table PART_TB_NAME split partition pmax
at(to_date('2014-01-31','yyyy-mm-dd')) into (partition P20140131,partition
pmax);
select
COUNT(1) from PART_TB_NAME
partition(P20131231);--2
select COUNT(1) from PART_TB_NAME
partition(P20140131);--1
select COUNT(1) from PART_TB_NAME partition(PMAX);
--0 接着再去追击分区
6、检查是否分区中还有子分区
SELECT * FROM dba_tab_subpartitions;
--查看是否有复合分区
7、检查分区索引
SQL> column INDEX_NAME format a30
SQL> column PARTITION_NAME format a30
SQL> SELECT index_name, NULL partition_name, status
2 FROM dba_indexes
3 WHERE table_name = upper('PART_TB_NAME')
4 AND partitioned = 'NO'
5
UNION
6
SELECT index_name, partition_name, status
7
FROM user_ind_partitions
8 WHERE index_name IN
9
(SELECT index_name
10 FROM dba_indexes
11 WHERE table_name = upper('PART_TB_NAME'))
12 ORDER BY 1, 2, 3;
INDEX_NAME PARTITION_NAME STATUS
------------------------------
------------------------------ --------
PK_PART_TB_NAME VALID
8、重建全局索引
drop index idx_part_tb_name
;--这个是存在风险的,尤其是也的数据量很大的时候,操作需谨慎。
create index
idx_part_tb_name
on part_tb_name (opt_dt) global
partition by
range (opt_dt)
(
partition P20131231 values less than (to_date('2014-01-01
00:00:00','SYYYY-MM-DD
HH24:MI:SS')) tablespace testdata1,
partition p20140131 values less than (to_date('2014-02-01
00:00:00','SYYYY-MM-DD
HH24:MI:SS')) tablespace testdata1,
partition PMAX values
less than (maxvalue) tablespace
testdata1
);
9、创建本地索引
create index idx_part_tb_name on part_tb_name(opt_dt) local;
10、摘录总结
比较表级别分区操作的索引分区维护
|
表级分区操作
|
非分区索引
|
本地分区索引
|
全局分区索引
|
|
增加分区
|
索引不受影响
|
索引不受影响
|
索引不受影响
|
|
拆分分区
|
整个索引被标记为UNUSABLE
|
受拆分操作影响的分区上的索引被标记为UNUSABLE
|
索引的所有分区都被标记为UNUSABLE
|
|
移动分区
|
整个索引被标记为UNUSABLE
|
被移动的分区上的索引被标记为UNUSABLE
|
索引的所有分区都被标记为UNUSABLE
|
|
交换分区
|
整个索引被标记为UNUSABLE
|
被交换的分区上的索引被标记为UNUSABLE
|
索引的所有分区都被标记为UNUSABLE
|
|
合并分区
|
整个索引被标记为UNUSABLE
|
受合并操作影响的分区上的索引被标记为UNUSABLE
|
索引的所有分区都被标记为UNUSABLE
|
|
截断分区
|
整个索引被标记为UNUSABLE
|
索引不受影响
|
索引的所有分区都被标记为UNUSABLE
|
|
删除分区
|
整个索引被标记为UNUSABLE
|
本地索引分区被删除,其余索引分区不受影响
|
索引的所有分区都被标记为UNUSABLE
|
|
令数据只读
|
不可能实现,除非整个表示静态的
(表上没有DML操作)
|
通过表空间隔离可以令分区级别索引数据只读
|
理论上可以令分区级别索引数据只读。
实际上无法实现,除非整个表是静态的
|
11、程序自动添加分区脚本
--判断当日的表分区是否已经创建
SELECT COUNT(1)
INTO v_count
FROM user_tab_partitions
WHERE table_name = 'PART_TB_NAME'
AND partition_name
= 'P'
|| to_char(SYSDATE,
'yyyymmdd');
--如果没有创建当日数据的分区,主动为分区表添加分区结构
IF v_count = 0 THEN
var_sql := 'alter table
PART_TB_NAME add PARTITION p' ||
to_char(SYSDATE, 'yyyymmdd') ||
' VALUES LESS THAN (TO_DATE(''' ||
to_char(SYSDATE +
1,
'yyyymmdd') ||
''',''yyyymmdd))
tablespace testdata'
||
to_char(SYSDATE, 'MM');
dbms_utility.exec_ddl_statement(var_sql);
END IF;
12、Oracle11g新特性
11g自动分区技术:
CREATE TABLE partition_table
(
OBJECT_ID
NUMBER,
OBJECT_TYPE VARCHAR2(128),
CREATED DATE
)
PARTITION BY
RANGE (CREATED)
INTERVAL(NUMTOYMINTERVAL(1, 'month'))
(PARTITION P20131130 VALUES LESS THAN (TO_DATE('2013-12-01', 'yyyy-mm-dd')));
--这样,就会每个月系统自动生成一个分区
--INTERVAL
(NUMTODSINTERVAL(1,'day')) 表示每天
--INTERVAL
(NUMTOYMINTERVAL(1,'YEAR')) 表示每年
13、分区表的相关维护
本部分摘录于网络博客。
1、增加表分区
--range
partitioned table
ALTER TABLE PART_TB_NAME ADD P20131231 VALUES LESS THAN (TO_DATE('2014-01-01
00:00:00','yyyy-mm-ddhh24:mi:ss'));
--list
partitioned table
ALTER TABLE list_partition ADD PARTITION01 VALUES ('100');
--Adding
Values for a List Partition
ALTER TABLE list_partition MODIFY PARTITION
PARTITION02 ADD VALUES('200');
--Dropping
Values from a List Partition
ALTER TABLE list_partition MODIFY PARTITION
PARTITION01 DROP VALUES('100');
--hash
partitioned table
ALTER TABLE hash_partition ADD PARTITION03;
--增加subpartition
ALTER TABLE range_hash_partition MODIFY
PARTITIONTEST ADD SUBPARTITION PARTITIONTEST1;
注:hash partitioned table 新增partition时,现有表的中所有data都有重新计算hash值,然后重新分配到分区中。所以被重新分配的分区的indexes需要rebuild
。
2、删除分区
ALTER TABLE PART_TB_NAME DROP PARTITION PMAX;
3、分区合并
1)合并父分区
ALTER TABLE PART_TB_NAME MERGE Partition1,
Partition2 INTO PARTITION
Partition3 UPDATE INDEXES;
--如果省略update
indexes子句的话,必须重建受影响的分区的index;
ALTER TABLE PART_TB_NAME MODIFY Partition2 REBUILD UNUSABLE
LOCAL INDEXES;
2)合并子分区
ALTER TABLE merge_partition
MERGE SUBPARTITIONS Partition1, Partition2 INTO SUBPARTITION Partition2 UPDATE INDEXES;
4、转换分区
可以将分区表转换成非分区表,或者几种不同分区表之间的转换。
CREATE TABLE hash_part02 AS SELECT * FROM hash_partition WHERE 1=2;
ALTER TABLE hash_partition EXCHANGE Partition2
WITH TABLE hash_part02;
这时,分区表hash_partition中的Partition2分区的资料将被转移到hash_part02这个非分区表中。
本文链接:http://www.cnblogs.com/oracle-dba/p/3496228.html,转载请注明。
博客园_首页
本频道文章均来源于网络,如有版权问题请联系我们,我们将尽快处理,感谢您的支持!