Oracle大表改为分区表及表空间切换方案

Oracle大表改为分区表及表空间切换方案

一、            背景

由于之前数据库表和索引放在一个表空间导致表空间数据文件增长太快,文件数量即将达到Oracle表空间的限制,需要对表(没有分区,有些表数据量多达几十亿,文件大小TB级)进行表空间迁移,并对某些表改造为分区表。

二、            可选方案分析

1.    使用IMP/EXP

导入(import)导出(export)工具年头已久,将数据导出为二进制文件,将会在11g r2之后废弃,只用于遗留数据的导入导出

此工具可以完成所需功能,但有如下限制:

1)         导出数据量大时非常慢,只能分批操作

2)         不支持表名映射,需要第三个用户或者数据库参与

3)         需要操作用户有DBA权限

4)         需要有IMP/EXP工具操作权限

5)         在客户端操作,受到网络影响

2.    使用IMPDP/IMPDP

EXPDP/IMPDP工具从10g开始引入,参数格式与EXP/IMP类似

优点:

1)         可以并发执行导入导出任务

2)         可以导入导出多个文件

3)         无需缓存,直接操作数据库和目标文件

4)         不受网络影响,expdp服务端程序

5)         支持对象映射,可直接映射表空间和表

6)         可以从未分区表导入到分区表

缺点:

1)         需要服务器约5TB的磁盘空间来存储二进制文件,可以分批导出

2)         一次性导入undo空间要足够大

3.    使用alter table ** move tablespace ***

此命令是将一个表移动到另外一个表空间中

优点:

1)         对于大表move时,对此表的查询不受影响,只有DML操作受影响

2)         索引结构不受影响,只需move完成后rebuild

3)         与其它对象依赖关系不受影响,操作前不必为对象间的依赖关系操心

4)         move操作可以parallel。

5)         NOLOGGING选项可大大加快重建速度,如果要move的表是nologging的,则不需指定

缺点:

1)         当前的用户必须对原表空间和新表空间都有操作权限

2)         不能改变表结构从普通表转换为分区表

3)         数据太大可能操作不成功

4)         经过验证不会释放原表空间数据文件已经格式化的磁盘空间

5)         当目标表空间不足时会中途才提示失败

4.    采用表重定义

把一个数据量非常大的普通表改造成分区表,如果离线操作能够解决问题,就不要用在线重定义,例如一些静态数据、历史数据的归档迁移,可使用CTAS、alter table move、或导出导入完成

使用场景:

1)         修改表的物理属性、存储参数

2)         将表迁移到别的表空间

3)         消除表碎片、释放空间

4)         在表中增加、删除或重命名字段

5)         大批量改变表中的数据

原理:

通过DBMS_REDEFINITION包来实现,首先会创建一个快速刷新的物化视图作为过渡表,然后将源表的数据加载到过渡表中,并在源表上创建物化视图日志,以支持快速刷新同步数据

限制条件与风险:

1)         使用基于主键的方式,则原表与重定义后的表必须有相同的主键

2)         使用基于ROWID的方式,不能是索引组织表

3)         有物化视图或者物化视图日志的表、物化视图容器表、高级队列表、索引组织表的溢出表、拥有BFILE,LOGN列的表、 Cluster表、sys和system下的表、临时表不能在线重定义

4)         不支持水平数据子集

5)         在列映射时只能使用有确定结果的表达式,如子查询就不行

6)         中间表有新增列,则不能有NOT NULL约束

7)         原表和中间表之间不能有引用完整性

8)         在线重定义无法采用nologging

9)         表空间至少要留有比源表所用空间更大的剩余空间,也就说至少要事先创建5T的表空间

10)     对业务的影响小,但过程耗时较长,测试两千万的数据花费十多分钟   20

11)     如果源表上的事务操作过于频繁,可能会发生较严重的等待,不存在事务

参考:https://www.sohu.com/a/166577098_505827

5.    采用CATS +RENAME

CTAS这种方法采用DDL语句,不产生UNDO,只产生少量REDO,建表后数据已经在分布到各个分区中,最后交换源表与目标表的名字即可

核心sql:create table t(id, time) partition by range (time) (partition t1 values less than (to_date(‘201311‘, ‘yyyymm‘)), partition t2 values less than (maxvalue)) nologging parallel 4 as select /*+parallel*/ id, time from s;

性能提升方式:

1)   加nologging:alter table t nologging;完成后根据需要将表修改为logging

2)   并行DDL: alter session enable parallel dml;

3)         查询并行

6.    采用INSERT+RENAME

这种方法适用于包含大数据量的表转到分区表中的一个分区的操作,就是先建立分区表结构然后使用insert来实现,将满足一个分区的数据查到某个中间表中,然后交换中间表和目标表的分区,每个部分都做完后交换源表与目标表的名字(alter table p exchange partition p1 with table t)。

性能提升:

1)         表修改为nologging

2)         启用并行DML,alter session enable parallel dml;

3)         采用 append方式插入

4)         所有数据插入完成后再建索引

不足:

1)         仍然存在一致性问题,交换分区之后RENAME T_NEW TO T之前,查询、更新和删除会出现错误或访问不到数据,不过当前不存在

2)         要求数据分布到多个分区中,会增加操作的复杂度,效率也会降低

7.    数据清洗方式

这种方法就是先建立表结构,然后建立任务每个一段时间,从源表查询一定时间方位内的数据插入到新表中,最后交换源表与目标表的名字,操作简单。

性能提升:

5)         表修改为nologging,

6)         数据插入完成后再建索引

7)         启用并行DML,alter session enable parallel dml;

8)         采用 append方式插入

三、            迁移原则

  1. 将所有的索引都放在TM_INDX表空间
  2. 迁移后的表(或者分区)尽量均匀分布在新的表空间
  3. 选择合适的表结构(聚簇表、IOT、分区表…),提升查询性能、可维护性
  4. 合理设置表结构的参数,提升查询性能、节约存储空间
  5. 选择合适的索引(函数、位图…)、删除不合理的无用的索引

四、            迁移步骤

1.    小表

对于小表或者数据量稳定的表不需要分区,不需要做表空间迁移,或者直接采用方案5(ctas+rename)方式均匀迁移到新的表空间中

2.    迁移大表

首先排除方案3(不能释放空间)和方案4(效率低,基本不涉及事务)

1)         确认需要操作的表(迁移、重建、删除)

2)         删除功能重复的表

3)         先迁移数据量相对比较小的表(10-100G),分别验证方案1、2、5、6、7的效率和可行性

4)         根据验证结果选择最优的方式迁移大表

3.    索引

将用不到的索引删除

将所有放在TM_DATA表空间的索引rebuild到TM_INDX表空间

原文地址:https://www.cnblogs.com/muphy/p/11595264.html

时间: 2024-11-05 11:23:06

Oracle大表改为分区表及表空间切换方案的相关文章

Oracle在线重定义(online redefinition)--将普通表改为分区表

使用Oracle的在线重定义技术,可以将Oracle的普通表改为分区表.操作如下: STEP1:测试表是否可以在线重定义,这里以unixdev数据库的LIJIAMAN.BSTEST为例 EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('LIJIAMAN','BSTEST', DBMS_REDEFINITION.CONS_USE_PK); 如果表上没有主键,则会报错:SQL> exec dbms_redefinition.start_redef_table('LIJI

使用ORACLE在线重定义将普通表改为分区表

1.首先建立测试表,并插入测试数据: create table myPartition(id number,code varchar2(5),identifier varchar2(20)); insert into myPartition values(1,'01','01-01-0001-000001'); insert into myPartition values(2,'02','02-01-0001-000001'); insert into myPartition values(3,

oracle大数据量。表分区提示查询效率

现在业务有一张usertrack 日志记录表.每天会产生30万条数据.数据量大查询效率会非常慢 所以我考虑通过表分区来提示效率  逻辑上是一张表.但是分区后会按照分区条件将数据分在不同的物理文件 优点: 1)   改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度. 2)   增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用: 3)   维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可: 4)   均衡I/O:可以把不同的分区映射到磁盘以平衡I

如何创建ORACLE大文件表空间

SQL>CREATE BIGFILE TABLESPACE 表名datafile 'd:\ndo\ddo\表名.DBF‘SIZE 500M AUTOEXTEND ON; SQL>Create Bigfile tablespace  bf_images_xpdatafile 'e:\datacenter\bf\bf_images_xp.dbf'  size 500M Autoextend on;//说明如下://创建一个大表空间,名称为:bf_images_xp,数据文件为e:\datacent

【Oracle批量更新】根据一个大表批量更新另一大表的方法比较

[问题]现在有两个千万级别的结构相同数据不同数据表T_SMS_PHONENO(目的表),T_SMS_PHONENO2(源表),根据源表数据更新目的表的数据. [分析]根据经验,更新方法一般有以下几种: 1.直接update. update T_SMS_PHONENO T Set    T.NAME=(select NAME from T_SMS_PHONENO2 where PHONENO=T.PHONENO) 2.采用分条更新.根据记录ID逐条更新. open cur is select ph

Oracle DB 使用连接显示多个表中的数据

? 编写SELECT语句,以使用等值联接和非等值联接访问多个表中的数据 ? 使用自联接将表联接到自身 ? 使用OUTER联接查看通常不满足联接条件的数据 ? 生成两个或多个表中所有行的笛卡尔积 ? JOIN的类型及其语法 ? 自然联接: – USING子句 – ON子句 ? 自联接 ? 非等值联接 ? OUTER联接: – LEFT OUTER联接 – RIGHT OUTER联接 – FULL OUTER联接 ? 笛卡尔积 – 交叉联接 获取多个表中的数据 有时需要使用多个表中的数据.如两个独立

Oracle Temp 表空间切换

一.TEMP表空间作用 临时表空间主要用途是在数据库进行排序运算.管理索引.访问视图等操作时提供临时的运算空间,当运算完成之后系统会自动清理.当 oracle 里需要用到 sort 的时候, PGA 中 sort_area_size 大小不够时,将会把数据放入临时表空间里进行排序,同时如果有异常情况的话,也会被放入临时表空间 , 正常来说,在完成 Select 语句.create index 等一些使用 TEMP 表空间的排序操作后, Oracle 是会自动释放掉临时段的.注意这里的释放,仅仅是

Oracle Study之案例--异构平台传输表空间(Linux至AIX)

Oracle Study之案例--异构平台传输表空间(Linux至AIX) 系统架构: 可                   源    库               目标库 操作系统 Linux RH6    AIX 5.3-09 主机名 rh6(192.168.8.245) aix211(192.168.8.211) 数据版本 Oracle 11gR2 Oracle 11gR2 数据库名 prod orcl 表空间 test1 test1    可传输表空间概述 Oracle 的可传输表空

oracle中用SQL语句创建和管理表

表名和列名的命名规则: 必须以字母开头 必须在1-30个字符之间 只能包含A-Z,a-z,0-9,_,$,# 不能与用户定义的其它对象重名 不能使用ORACLE的保留字 创建前具备的条件: CREATE TABLE权限 建表时必须指定: 表名 列名,列的数据类型,最大长度 数据类型: varchar2(size) 变长字符型(最大长为4000字符) char(size)  定长字符型(最大2000字符) number(p,s)  数值型 date   日期型 long   变长大字符型(最大2G