`
guiqing1
  • 浏览: 1533 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

oracle 分区

 
阅读更多
有一个需求,将某业务表的某个时间点之前的记录转移到它的历史表中。如果当前业务表不是基于这个业务时间点的分区表设置,那只能insert再delete操作。这种转移数据的方法非常非常低基础。经常在初级的数据库管理人员和开发人员的程序中出现。不是说这个方法不好,对于转移的记录数量在几十几百条,而转移频率高,转移时间点随机的情况而言,这个方法还是挺管用的。但如果转移的数据量一次数以百万计的话,这种方法就显得低效了。
因此,在Oracle数据库开发中,对于这种大数据的转移可以使用分区表交换技术实现。即使你一次转移的数据量几亿甚至几十亿也没有关系,转移时间依然是毫秒级的。这个方法大体流程是这样:
首先,你需要将当前表修改为分区表,找到分区字段很关键;其次,这个分区表的索引都建立成本地索引,全局索引就不要了,原因后面介绍;再次,建立一个对应的临时非分区表,表结构和这个一样;最后使用alter table table_name exchange partition  Partition_name with table table_name_exchange;操作,将表分区所拥有数据的实际物理存储空间段相互交换,这是指针级的操作。
这样就完成了这个表分区数据的快速转移。
第一步,准备环境

建立一张测试表SALE,它的分区字段是DOTIME,按照季度进行分区。



Sql代码
CREATE TABLE SALE  
(  
  DOTIME          DATE                          DEFAULT sysdate,  
  BILLID          VARCHAR2(20 BYTE)             NOT NULL,  
  FROMARREAR      NUMBER(16,4)                  DEFAULT 0  
)  
PARTITION BY RANGE (DOTIME)  
(   
  PARTITION PY11Q3 VALUES LESS THAN (TO_DATE(' 2011-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))  
    LOGGING,   
  PARTITION PY11Q4 VALUES LESS THAN (TO_DATE(' 2012-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))  
    LOGGING,   
  PARTITION PY12Q1 VALUES LESS THAN (TO_DATE(' 2012-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))  
    LOGGING,   
  PARTITION PY12Q2 VALUES LESS THAN (TO_DATE(' 2012-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))  
    LOGGING,   
  PARTITION P_MAX VALUES LESS THAN (MAXVALUE)  
    LOGGING  
)  


CREATE TABLE SALE
(
  DOTIME          DATE                          DEFAULT sysdate,
  BILLID          VARCHAR2(20 BYTE)             NOT NULL,
  FROMARREAR      NUMBER(16,4)                  DEFAULT 0
)
PARTITION BY RANGE (DOTIME)
(
  PARTITION PY11Q3 VALUES LESS THAN (TO_DATE(' 2011-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    LOGGING,
  PARTITION PY11Q4 VALUES LESS THAN (TO_DATE(' 2012-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    LOGGING,
  PARTITION PY12Q1 VALUES LESS THAN (TO_DATE(' 2012-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    LOGGING,
  PARTITION PY12Q2 VALUES LESS THAN (TO_DATE(' 2012-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    LOGGING,
  PARTITION P_MAX VALUES LESS THAN (MAXVALUE)
    LOGGING
)
;

再建立一张交换表,表的字段结构和分区表完全一致。



Sql代码
create table SALE_exchange  
(  
  DOTIME          DATE                          DEFAULT sysdate,  
  BILLID          VARCHAR2(20 BYTE)             NOT NULL,  
  FROMARREAR      NUMBER(16,4)                  DEFAULT 0  
); 

create table SALE_exchange
(
  DOTIME          DATE                          DEFAULT sysdate,
  BILLID          VARCHAR2(20 BYTE)             NOT NULL,
  FROMARREAR      NUMBER(16,4)                  DEFAULT 0
);

注意,分区表上的主键所属的全局唯一索引不要了,改成SALE (BILLID,DOTIME)上的本地索引,这样也能保证数据的一致性。原来的主键字段billid必须放在前面,防止原来原来基于billid直接查询操作的性能下降太多。

create unique index PK_SALE on SALE (BILLID,DOTIME) local;

本地分区索引创建完毕。


第二步,
检查一下数据记录情况。假设我们要将PY11Q3分区中的记录转移走。
select count(*) from SALE partition(PY11Q3);
select  count(*)  from SALE_exchange;

第三步,转移数据

alter table SALE exchange partition  PY11Q3 with table SALE_exchange;

一个命令,将分区段和表段的空间指针互相替换,就实现了这个分区表的业务数据的转移工作。

第四步,检查索引状态

分区表这点不好,如果分区发生改变,如exchange,move,split等,那么该分区上的本地索引分区就会失效,同时整个分区表上的全局索引也会失效。所以我最开始说全局索引需要撤销了,就是这个道理。试想,如果这时还有全局索引存在,那它失效了,这就将影响到分区表的其他业务操作。

不管怎样,都需要检查一下索引状态。



Sql代码
select index_name, partition_name, status  
  from user_ind_partitions  
where status = 'UNUSABLE' 
union all 
select index_name, '' as partition_name, status  
  from user_indexes  
where status = 'UNUSABLE'; 

select index_name, partition_name, status
  from user_ind_partitions
where status = 'UNUSABLE'
union all
select index_name, '' as partition_name, status
  from user_indexes
where status = 'UNUSABLE';

这里,本地分区索引的索引分区肯定失效了。原来exchange表上的索引也会失效。它们都需要重建。
分区索引的重建:
alter index PK_SALE rebuild partition PY11Q3;

alter index PK_SALE_EXCHANGE rebuild;


经过这样的操作之后,历史数据是从当前业务表移出来了,但它在一个临时的孤立的表中。在现实业务中,这样的数据是需要移动历史表中。当然,如果你有转换操作,你可以继续使用insert 方法转移。如果没有,你还可以使用分区交换技术,将这个数据交换到历史表中。

简而言之,Oracle分区表技术在大数据量表的操作中建议经常使用,它的很多特性有助于我们开发出高效的应用程序。

Example:
删除一年以前的数据:
create or replace procedure drop_partition AS
v_part_name varchar2(100);--要添加分区表的名称前缀
v_over_time number; --过期时间间隔
v_err_num number; --ORA错误号
v_err_msg varchar2(100); --错误描述

begin
--得到时间最早的分区
select min(partition_name) into v_part_name
from user_tab_partitions where table_name='SALE_DATA';
--得到时间最早的分区到当前的时间间隔
select months_between(sysdate,to_date(substr(min(partition_name),7,8),'yyyy-mm')) into v_over_time
from user_tab_partitions where table_name='SALE_DATA';
--删除最早的分区
if v_over_time>12 then
execute immediate 'alter table sale_data drop parttition'|| v_part_name;
end if;
exception
when others then
v_err_num := SQLCODE
v_err_msg := SQLSTR(SQLERRM,1 ,100);
dbms_output.put_line('执行错误:'|| v_err_num || '错误描述:'|| v_err_msg);
end drop_partition;

--创建一个job,每天run一次,定时删除
declare
   job name
begin
   dbms_job.submit(job,'drop_partition;',sysdate,'sysdate+1');
end;
分享到:
评论

相关推荐

    Oracle分区技术介绍

    Oracle分区技术是一种数据库管理系统(DBMS)特性,用于将大型表和索引分割成更小、更易管理和处理的部分,从而提升查询性能和数据管理效率。这种技术特别适用于数据仓库和决策支持系统(DSS),因为这些系统通常...

    ORACLE分区

    根据提供的文件信息,本文将详细解释Oracle分区技术及其在解决UNDOTBS01.DBF文件过大问题中的应用方法,并进一步探讨Oracle分区的不同类型及其应用场景。 ### Oracle 分区概述 Oracle分区是一种将大表或索引分割成...

    Oracle分区表用法

    【Oracle分区表用法】 Oracle分区表是一种高级的数据库管理技术,它将大型表的数据分散存储在不同的物理区域,以提升查询效率和系统的整体性能。本文将详细介绍分区表的概念、作用、优缺点,以及各种类型的分区表...

    Oracle 分区表自动维护脚本

    标签“oracle分区表 自动维护”概括了脚本的核心功能和使用场景,说明脚本主要用于Oracle数据库的分区表自动维护。 从提供的部分内容中,我们可以看到脚本的具体实现细节: 1. 创建基础表`PART_T_MAINTENANCE`,...

    Oracle分区表培训

    Oracle分区表是数据库管理系统Oracle中的一个高级特性,用于将大表分成较小、更易管理的部分,从而提高查询性能,优化存储管理和数据维护。在大型企业级应用中,尤其是在处理大量数据时,分区表是不可或缺的技术手段...

    Oracle分区表及分区索引

    Oracle 分区表及分区索引 Oracle 分区表是指将一个大表分割成多个小表,每个小表称为一个分区,分区表的优点是可以提高查询性能、改善管理型、增强容错性等。 分区表的分类: 1. 范围分区(Range Partitioning) ...

    深入学习分区表及分区索引(详解oracle分区).docx

    Oracle分区技术是数据库管理系统中用于优化大规模数据存储和查询性能的一种高级特性。它允许将大表和索引分成较小、更易管理和操作的部分,每个部分称为一个分区。分区的主要目标是提高查询性能、简化管理任务并增强...

    Oracle分区表详解

    ### Oracle 分区表详解 #### 一、Oracle 分区简介 Oracle 的分区技术是一种用于管理和优化超大型表和索引的有效手段。通过将一个大型的表或者索引分割成多个较小且可管理的部分,分区技术能够显著提升数据库的性能...

    oracle分区表之hash分区表的使用及扩展

    Oracle分区表中的Hash分区是一种基于哈希算法的分区策略,适用于处理无法清晰定义分区范围的大型数据表。这种分区方式通过计算分区键的哈希值来决定数据存储在哪个分区,以此达到数据分散和负载均衡的目的。Hash分区...

    Oracle分区表和锁的应用

    下面我们将深入探讨Oracle分区表和锁的应用。 一、Oracle分区表 1. **分区概念**:Oracle分区表是将一个大表逻辑上划分为多个较小的部分,每个部分称为一个分区。每个分区都有自己的索引和维护操作,这使得对大...

    oracle分区资料·

    oracle分区资料· oracle分区资料· oracle分区资料·

    导入导出 Oracle 分区表数据

    ### 导入导出Oracle分区表数据 #### 一、概述 在Oracle数据库管理中,对分区表进行数据的导入与导出是一项常见的任务。分区技术可以显著提高大型表的性能,尤其是在处理大规模数据集时。为了有效地管理和迁移这些...

    ORACLE分区表的概念及操作

    总结来说,Oracle分区表是一种有效管理大规模数据的手段,通过合理分区,可以显著提升查询效率,简化维护工作,并提供更高的数据可用性。然而,使用分区也需要权衡其带来的复杂性和额外的存储需求。正确理解和应用...

    ORACLE分区表的创建

    ### ORACLE 分区表的创建详解 #### 一、概述 在Oracle数据库中,分区是一种高效的数据管理方式,尤其适用于大型表和索引组织表。通过将数据逻辑地分割成多个独立的部分(即分区),可以显著提高查询性能,并简化表...

    Oracle 分区表 分区索引

    #### 一、Oracle分区概述 在Oracle数据库中,分区技术是一种非常有效的管理大型表和索引的方法。通过将一个大的表或索引分成多个较小的部分(分区),可以显著提高查询性能,并简化表和索引的管理。 #### 二、何时...

    Oracle 分区表全揭秘

    Oracle 分区表全揭秘 ,非常详细,oracle dba可以看看

    oracle分区表总结

    #### 一、Oracle分区表概述 在Oracle数据库中,分区是一种对大型表进行物理分割的方法,它可以显著提高查询性能并简化数据管理任务。通过将一个大表分成多个较小的部分(即分区),可以更快地执行查询操作,尤其是...

    oracle分区技术-大批量数据操作

    简单讲解了oracle分区技术-大批量数据操作

Global site tag (gtag.js) - Google Analytics