我可以在oracle中从月到日更改范围间隔分区吗

Can i change range interval partition from month to day in oracle

我有一个 table 分区如下,有数百万行数据。 Table 大小为 120 GB。

PARTITION BY RANGE (Read_time) INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))

现在我想更改为现有数据和未来数据的这种分区策略。 Table 每天按作业插入。

 PARTITION BY RANGE (Read_time) INTERVAL(NUMTODSINTERVAL(1, 'DAY'))

我有 12 个月的分区(18 年 10 月到 19 年 11 月)。我想将分区转换为白天。

例如:对于 Jul'19 分区,应该拆分为 2019 年 7 月 1 日, 2019 年 7 月 2 日 ………… 19 年 7 月 31 日。

数据也应该移动到新分区

我试过拆分分区。新分区已在当天创建,但行未移动到新分区。

将每月间隔更改为每天很简单

 ALTER TABLE test SET INTERVAL (NUMTODSINTERVAL(1,'DAY'));

有关详细信息,请参阅 documentation

让我们用一个小例子来说明

create table test 
(dt date)
PARTITION BY RANGE (dt)
INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(
   PARTITION part_01 values LESS THAN (TO_DATE('01-01-2019','DD-MM-YYYY'))
);

insert into test (dt)
select date'2019-01-01' + rownum dt from dual 
connect by level <= 100;

每月间隔中的 table 分区并包含 100 天的数据 - 在一个初始分区和 4 个新的每月分区中生成。

PARTITION_NAME                 HIGH_VALUE                                                                      
------------------------------ --------------------------------------------------------------------------------
PART_01                        TO_DATE(' 2019-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93334                     TO_DATE(' 2019-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93335                     TO_DATE(' 2019-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93336                     TO_DATE(' 2019-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93337                     TO_DATE(' 2019-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

现在我们切换到每日分区

 ALTER TABLE test SET INTERVAL (NUMTODSINTERVAL(1,'DAY'));

对现有数据没有任何影响(所以它是即时操作),而且当前月份的新数据将进入当前(月份)分区。

新月加载的数据将按天分区。

让我们插入几天

insert into test (dt)
select date'2019-01-01' + 100 +rownum dt from dual 
connect by level <= 22;


PARTITION_NAME                 HIGH_VALUE                                                                      
------------------------------ --------------------------------------------------------------------------------
PART_01                        TO_DATE(' 2019-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93334                     TO_DATE(' 2019-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93335                     TO_DATE(' 2019-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93336                     TO_DATE(' 2019-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93337                     TO_DATE(' 2019-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93338                     TO_DATE(' 2019-05-02 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93339                     TO_DATE(' 2019-05-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93340                     TO_DATE(' 2019-05-04 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

正如预期的那样,从 5 月开始,每天对数据进行分区。

如果您还需要对历史数据进行重新分区,这将需要使用 split partition 进行重组(数据移动 - 120GB 需要一些时间)。

alter table test
    SPLIT PARTITION FOR(TO_DATE('2019-02-01','yyyy-mm-dd'))
    AT (TO_DATE('2019-02-27','yyyy-mm-dd'));
alter table test
    SPLIT PARTITION FOR(TO_DATE('2019-02-01','yyyy-mm-dd'))
    AT (TO_DATE('2019-02-26','yyyy-mm-dd'));

这会在新分区中拆分最后一天,您必须在每个月分区中的每一天都这样做。

在此步骤之后,历史数据也会按天进行分区:

select * from test partition for ( DATE'2019-02-26');  

DT                 
-------------------
26.02.2019 00:00:00