Oracle 通过脚本一键生成按月分区表

简介: Oracle 通过脚本一键生成按月分区表

前言


分区表作为Oracle三大组件之一,在Oracle数据库中,起着至关重要的作用。


分区表有什么优点?


  • 普通表转分区表:应用程序无感知,DML 语句无需修改即可访问分区表。
  • 高可用性:部分分区不可用不影响整个分区表使用。
  • 方便管理:可以单独对分区进行DDL操作,列入重建索引或扩展分区,不影响分区表的使用。
  • 减少OLTP系统资源争用:因为DML分布在很多段上进行操作。
  • 增强数据仓库的查询性能:可按时间进行分区查询,加速查询。


在运维开发过程中,发现有部分应用厂商在建表之初并未考虑到数据体量的问题,导致很多大表都没有建成分区表。在系统运行过程中,这些表的数据量一直在增大,当达到一定体量时,我们就需要考虑对其进行分区表转换,以提高数据库的性能。那么,如何操作呢?


一、介绍


普通表转换为分区表,Oracle给我们提供了哪些方式呢?


  • 数据泵导入
  • 子查询方式插入
  • 分区交换
  • 在线重定义
  • ALTER TABLE…MODIFY…方式(12.2之后支持)


以上几种方式中,我比较常用的是:数据泵导入,子查询插入,在线重定义。这三种方式的共同点都是 需要提前创建分区表结构的中间表或者目标表。

二、脚本


在长时间的重复性工作中,“懒癌”发作的我就想着是否能通过自动化的方式构建分区表的建表语句呢?然后我发现了 梁敬彬大佬的 普通表自动转化为按月分区表的脚本。


经加工和提炼,将以上脚本修改为契合自己使用的脚本:


  • 用于生成CTAS完整分区表建表语句:ctas_par.prc
  • 用于CTAS直接转换为分区表:par_tab_deal.pkg点我跳转文末 可以获取 分区表脚本 以及博主的联系方式


par_tab_deal.pkg 的使用方式为:

--创建日志表 PART_TAB_LOG
create table PART_TAB_LOG
(
 TAB_NAME     VARCHAR2(200),
 DEAL_MODEL   VARCHAR2(200),
 SQL_TEXT     clob,
 DEAL_TIME    DATE,
 remark       VARCHAR2(4000),
 exec_order1  number,
 exec_order2  number
);
--执行分区表转换
BEGIN
  pkg_deal_part_tab.p_main(p_tab            => 't1',
                           p_deal_flag      => 1,
                           p_parallel       => 8,
                           p_part_colum     => 'created_date',
                           p_part_nums      => 24,
                           p_tab_tablespace => 'users',
                           p_idx_tablespace => 'users');
END;
--查看日志
select DBMS_LOB.SUBSTR(sql_text,1000)||';' from part_tab_log t where tab_name='T1' order by exec_order1,exec_order2;
select sql_text||';' from part_tab_log t where tab_name='T1' order by exec_order1,exec_order2;


ctas_par.prc 的使用方式:

--直接执行输出即可
BEGIN
  ctas_par(p_tab        => 't1',
           p_part_colum => 'created_date',
           p_part_nums  => 24,
           p_tablespace => 'users');
END;


三、实战应用


1、创建测试表T1

由于实验需要一张基础表,因此通过下方步骤创建表 T1:

--删除t1表
DROP TABLE t1 PURGE;
--创建t1表
CREATE TABLE t1 (
  id           NUMBER,
  description  VARCHAR2(50),
  created_date DATE,
  CONSTRAINT t1_pk PRIMARY KEY (id)
);
--创建索引
CREATE INDEX t1_created_date_idx ON t1(created_date);
--插入数据
INSERT INTO t1
SELECT level,
       'Description for ' || level,
       ADD_MONTHS(TO_DATE('01-JAN-2017', 'DD-MON-YYYY'), -TRUNC(DBMS_RANDOM.value(1,4)-1)*12)
FROM   dual
CONNECT BY level <= 10000;
COMMIT;


2、创建procedure


执行脚本创建procedure:

image.png

image.png

select  'alter  '||object_type||'   '||owner||'.'||object_name||'   compile;'
from  dba_objects t
where t.object_type='PROCEDURE'
and t.object_name='CTAS_PAR' ;

image.png


📢 注意:确认procedure已成功创建。


3 执行procedure

执行procedure生成CTAS创建分区表语句:


  • 表名:T1
  • 分区键:CREATED_DATE
  • 建立分区月数:24
  • 分区所在表空间:USERS
alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss";
BEGIN
  ctas_par(p_tab        => 'T1',
           p_part_colum => 'CREATED_DATE',
           p_part_nums  => 24,
           p_tablespace => 'USERS');
END;


执行脚本如下:

--分区表获取分区列最小记录日期:2015-01-01 00:00:00
--分区表ctas创建的完整语句如下: 
create table T1
partition BY RANGE(CREATED_DATE)(
partition T1_P201501 values less than (TO_DATE(' 2015-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201502 values less than (TO_DATE(' 2015-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201503 values less than (TO_DATE(' 2015-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201504 values less than (TO_DATE(' 2015-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201505 values less than (TO_DATE(' 2015-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201506 values less than (TO_DATE(' 2015-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201507 values less than (TO_DATE(' 2015-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201508 values less than (TO_DATE(' 2015-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201509 values less than (TO_DATE(' 2015-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201510 values less than (TO_DATE(' 2015-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201511 values less than (TO_DATE(' 2015-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201512 values less than (TO_DATE(' 2016-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201601 values less than (TO_DATE(' 2016-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201602 values less than (TO_DATE(' 2016-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201603 values less than (TO_DATE(' 2016-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201604 values less than (TO_DATE(' 2016-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201605 values less than (TO_DATE(' 2016-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201606 values less than (TO_DATE(' 2016-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201607 values less than (TO_DATE(' 2016-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201608 values less than (TO_DATE(' 2016-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201609 values less than (TO_DATE(' 2016-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201610 values less than (TO_DATE(' 2016-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201611 values less than (TO_DATE(' 2016-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201612 values less than (TO_DATE(' 2017-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_MAX values less than (maxvalue) tablespace USERS)
             nologging
             parallel 4
             enable row movement
             tablespace USERS
             as select /*+parallel(t,8)*/ * from T1_01 t where 1 = 2;
--附加日志和取消并行
alter table T1 logging;
alter table T1 noparallel;


如果只是需要分区表的建表语句,这里已经可以很简单的拼接出来:

create table T1
(
  id           NUMBER,
  description  VARCHAR2(50),
  created_date DATE
)
partition BY RANGE(CREATED_DATE)(
partition T1_P201501 values less than (TO_DATE(' 2015-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201502 values less than (TO_DATE(' 2015-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201503 values less than (TO_DATE(' 2015-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201504 values less than (TO_DATE(' 2015-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201505 values less than (TO_DATE(' 2015-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201506 values less than (TO_DATE(' 2015-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201507 values less than (TO_DATE(' 2015-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201508 values less than (TO_DATE(' 2015-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201509 values less than (TO_DATE(' 2015-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201510 values less than (TO_DATE(' 2015-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201511 values less than (TO_DATE(' 2015-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201512 values less than (TO_DATE(' 2016-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201601 values less than (TO_DATE(' 2016-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201602 values less than (TO_DATE(' 2016-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201603 values less than (TO_DATE(' 2016-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201604 values less than (TO_DATE(' 2016-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201605 values less than (TO_DATE(' 2016-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201606 values less than (TO_DATE(' 2016-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201607 values less than (TO_DATE(' 2016-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201608 values less than (TO_DATE(' 2016-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201609 values less than (TO_DATE(' 2016-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201610 values less than (TO_DATE(' 2016-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201611 values less than (TO_DATE(' 2016-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_P201612 values less than (TO_DATE(' 2017-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace USERS,
partition T1_MAX values less than (maxvalue) tablespace USERS)
ENABLE ROW MOVEMENT
TABLESPACE USERS;


4、CTAS创建分区表

实际执行前,需要先将原表T1进行 rename 操作:

alter table lucifer.T1 RENAME TO T1_01;

image.png


📢 注意: 如需创建分区表结构,无需修改以上脚本;如需直接创建分区表包含数据,需要将 where 1 = 2 修改为 where 1 = 1。


确保当前表T1已经rename为T1_01,执行CTAS创建分区表:

image.png

查看分区表结构:

image.png

📢 注意: 由于CTAS不会继承 注释,默认值,因此需要手动比对是否缺失。

COMMENT ON TABLE T1 IS '';
COMMENT ON COLUMN T1.ID IS '';
COMMENT ON COLUMN T1.CREATED_DATE IS '';
COMMENT ON COLUMN T1.DESCRIPTION IS '';


重命名原表的索引和约束:

--重命名索引
ALTER INDEX T1_CREATED_DATE_IDX RENAME TO T1_CREATED_DATE_IDX_01;
ALTER INDEX T1_PK RENAME TO T1_PK_01;
--重命名唯一约束
ALTER TABLE T1_01 RENAME CONSTRAINT T1_PK TO T1_PK_01;

image.png


分区表新建本地索引:

create index T1_CREATED_DATE_IDX on T1 (CREATED_DATE) tablespace users;
alter table T1 add constraint T1_PK primary key (ID) using index  tablespace users;


查询分区表:


通过以下查询可以发现,数据已被按月分到对应分区下。

SELECT COUNT(1) FROM t1;
SELECT COUNT(1) FROM t1 PARTITION(T1_P201501);
SELECT COUNT(1) FROM t1 PARTITION(T1_P201601);
SELECT COUNT(1) FROM t1 PARTITION(T1_MAX);


image.png

至此,脚本已经介绍完毕。


相关文章
|
7月前
|
存储 SQL Oracle
Oracle数据库批量删除表、视图、序列、存储过程、函数脚本
Oracle数据库批量删除表、视图、序列、存储过程、函数脚本
68 0
|
3月前
|
Oracle 关系型数据库 Linux
RHEL7.9系统下一键脚本安装Oracle 11gR2单机版本
RHEL7.9系统下一键脚本安装Oracle 11gR2单机版本
58 1
|
3月前
|
Oracle 关系型数据库 索引
Oracle-维护存在主键的分区表时的注意事项
Oracle-维护存在主键的分区表时的注意事项
71 0
|
3月前
|
SQL Oracle 关系型数据库
Oracle-使用切片删除的方式清理非分区表中的超巨数据
Oracle-使用切片删除的方式清理非分区表中的超巨数据
40 1
|
3月前
|
SQL 存储 Oracle
Oracle-分区表解读
Oracle-分区表解读
104 0
|
5月前
|
消息中间件 Oracle 关系型数据库
Flink CDC确实支持Oracle分区表的CDC
Flink CDC确实支持Oracle分区表的CDC
92 1
|
5月前
|
消息中间件 Oracle 关系型数据库
Flink CDC确实支持Oracle分区表的CDC,但是在配置时需要特别注意。以下是一些可能的解决方案
Flink CDC确实支持Oracle分区表的CDC,但是在配置时需要特别注意。以下是一些可能的解决方案
44 1
|
11月前
|
SQL 监控 Oracle
Oracle 性能监控统计工具 mystats脚本
看看这个工具的介绍就知道这个工具是很牛的,因为它是在两个牛人的工具是改进的,一出生就有贵族血统呀!
|
11月前
|
监控 Oracle 关系型数据库
oracle性能监控脚本 Mother Of All Tuning Scripts (MOATS)
这个名字牛吗?Mother Of All Tuning Scripts (MOATS) 下载地址: https://github.com/oracle-developer/moats,下载后
|
11月前
|
SQL Oracle 关系型数据库
Oracle 数据库日常健康检查脚本
检查数据库和online logfile的大小 —执行一下这3个SQL,把结果贴出来,看看数据库大小和log的切换频率。
182 0

推荐镜像

更多