签到成功

知道了

CNDBA社区CNDBA社区

Oracle 19c 在线将 普通表 转 分区表

2023-04-11 10:57 1192 2 原创 Oracle 19c
作者: dave

1 单表转分区表说明

在Oracle 10g的官方手册里有提到,当单表的大小超过2G的时候,就建议使用分区表。 当然这个数字在在之后版本的官方文档中删除了。

在10g 和 11g中,单表转分区表,我们有四种方法:https://www.cndba.cn/dave/article/116537

  1. Export/import method(导入导出)
  2. Insert with a subquery method(插入子查询的方法)
  3. Partition exchange method(交换分区法)
  4. DBMS_REDEFINITION(在线重定义)

在Oracle 12.2 版本之后,Oracle 支持直接通过ALTER TABLE .. MODIFY转换非分区表为分区表。https://www.cndba.cn/dave/article/116537

关于Oracle 12 架构的版本区别和特性,可以参考我之前的博客:https://www.cndba.cn/dave/article/116537

从生命周期的角度来谈谈Oracle 软件的版本(12c/18c/19c/20c/21c)问题
https://www.cndba.cn/dave/article/107944

Oracle 12.2 家族的补丁 RU 和 RUR 说明
https://www.cndba.cn/dave/article/4063

https://www.cndba.cn/dave/article/116537

《Oracle 18c 必须掌握的新特性》
https://www.cndba.cn/dave/article/3453

官网对VLDB的说明可以参考:

https://docs.oracle.com/en/database/oracle/oracle-database/19/vldbg/index.htmlhttps://www.cndba.cn/dave/article/116537https://www.cndba.cn/dave/article/116537

当然,在Oracle 12.2 家族的架构下,还是支持在线重定义的,只是补充了在直接MODIFY 的方法, 关于这两种方法的说明,可以参考官网:

4.6.1 Using Online Redefinition to Partition Collection Tables
https://docs.oracle.com/en/database/oracle/oracle-database/19/vldbg/evolve-nopartition-table.html#GUID-5C0F8D12-DDDF-42AB-B644-1880156832BC
4.6.2 Converting a Non-Partitioned Table to a Partitioned Table
https://docs.oracle.com/en/database/oracle/oracle-database/19/vldbg/evolve-nopartition-table.html#GUID-5FDB7D59-DD05-40E4-8AB4-AF82EA0D0FE5https://www.cndba.cn/dave/article/116537https://www.cndba.cn/dave/article/116537

https://www.cndba.cn/dave/article/116537

2 操作示例

我们先看官网的示例demo:

ALTER TABLE employees_convert MODIFY
  PARTITION BY RANGE (employee_id) INTERVAL (100)
  ( PARTITION P1 VALUES LESS THAN (100),
    PARTITION P2 VALUES LESS THAN (500)
   ) ONLINE
  UPDATE INDEXES
 ( IDX1_SALARY LOCAL,
   IDX2_EMP_ID GLOBAL PARTITION BY RANGE (employee_id)
  ( PARTITION IP1 VALUES LESS THAN (MAXVALUE))
 );

注意,在生产环境,建议在非业务高峰期,采用非ONLINE 方式进行转换。 虽然ONLINE 方式不影响DML操作,但还是不建议采用这种方式,毕竟Oracle 当初在线重建索引是有历史教训在那的。https://www.cndba.cn/dave/article/116537

创建测试表:

[dave@www.cndba.cn ~]$ sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Tue Apr 11 10:13:56 2023
Version 19.18.0.0.0

Copyright (c) 1982, 2022, Oracle.  All rights reserved.


Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.18.0.0.0

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 DAVE                           READ WRITE NO
SQL> alter session set container=dave;

Session altered.

SQL> CREATE TABLE CNDBA(ID NUMBER,WEBSITE VARCHAR2(30));

Table created.

SQL>

插入测试数据:

SQL> declare
  2  v1 number;
  3  begin
  4  for i in 1..300000
  5  loop
  6  execute immediate 'insert into CNDBA values(:v1,''www.cndba.cn'')' using i;
  7  end loop;
  8  commit;
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL>

添加主键索引:

SQL> alter table cndba add constraint pk_cndba primary key(id);
Table altered.

SQL> col index_name for a15
SQL> col status for a15
SQL> select index_name,status from user_indexes where index_name in ('PK_CNDBA');

INDEX_NAME      STATUS
--------------- ---------------
PK_CNDBA        VALID

SQL>

在线转分区:

SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

TO_CHAR(SYSDATE,'YYYY-MM-DDHH24:MI:SS')
---------------------------------------------------------
2023-04-11 10:41:20

SQL> ALTER TABLE CNDBA MODIFY
  2  PARTITION BY RANGE (ID)
  3  ( PARTITION P1 VALUES LESS THAN (100000),
  4  PARTITION P2 VALUES LESS THAN (200000),
  5  PARTITION P3 values less than (maxvalue)
  6  ) UPDATE INDEXES parallel 8; 

Table altered.

SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

TO_CHAR(SYSDATE,'YYYY-MM-DDHH24:MI:SS')
---------------------------------------------------------
2023-04-11 10:41:37

SQL>

此时索引已经变成了分区索引,注意并行度查看:

SQL> col degree for a15
SQL> select index_name,status,degree from user_indexes where index_name in ('PK_CNDBA');

INDEX_NAME      STATUS          DEGREE
--------------- --------------- ---------------
PK_CNDBA        N/A             1


SQL> col PARTITION_NAME for a15
SQL>  select index_name,partition_name, status,GLOBAL_STATS from dba_ind_partitions where index_name='PK_CNDBA';

INDEX_NAME      PARTITION_NAME  STATUS          GLOBAL_ST
--------------- --------------- --------------- ---------
PK_CNDBA        P1              USABLE          NO
PK_CNDBA        P2              USABLE          NO
PK_CNDBA        P3              USABLE          NO

查看表分区:

SQL> COL TABLE_NAME FOR A15
SQL> select TABLE_NAME,PARTITION_NAME from dba_tab_partitions where table_name='CNDBA';

TABLE_NAME      PARTITION_NAME
--------------- ---------------
CNDBA           P1
CNDBA           P2
CNDBA           P3

SQL>

这里要注意,对于生产环境,不建议使用ONLINE,另外当表很大,且表上索引较多的情况下,转换时间也会受索引影响。

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2241
    原创
  • 3
    翻译
  • 550
    转载
  • 187
    评论
  • 访问:6768662次
  • 积分:4258
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ