Possible to modify an existing partitioned Oracle table to utilize INTERVAL? [duplicate]

I have a table which is partitioned as below and has millions of rows of data. Table size is 120 GB.

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

Now I want to change to this partitioning strategy with existing data and future data. Table is inserted daily by job.

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

I have 12 month partition (Oct'18 to Nov'19). I want partition to be converted to daywise.

enter image description here For example: For Jul'19 partition, it should to be splitted to 01 Jul'19, 02 Jul'19 ....... 31 Jul'19.

Data should also be moved to new partition

I tried split partition. New partition got created day wise , but rows didn't move to new partition.

enter image description here

enter image description here


Solution 1:

To change for monthly interval to daily is a simple as

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

see the documentation for further details

Lets illustrate in on a small example

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;

The table in montly intrval partitioned and contains 100 days of data - yielding in one initial partition and 4 new montly partition.

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

Now we switch to daily partitioning

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

This makes nothing with existing data (so it is instant operation), also the new data for the current month will go in the current (month) partition.

The data loaded for the new month will be partitioned on daily basis.

Lets insert few new days

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

As expected starting with May the data are daily partitioned.

If you need also to re-partitioned your historical data, this will require reorganisation (data movement - will take some time for 120GB) using split partition.

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'));

This splits the last day in a new partition, you'll have to do it for each day in each monthly partition.

After this step also the history data is partitioned per day:

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

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