Oracle Table level partition - add INTERVAL to existing partition by range - oracle

I have some tables in an Oracle database which I have partitioned by range. It seems that the default interval of partition is 1 day.
I want to update this to use INTERVAL(NUMTODSINTERVAL(5,'DAY')) so that the partition is created for every 5 days and not every day.
How do I update my existing script which uses only "Partition by range" and not uses partition by range interval. Please help.

with
alter table … set interval(NUMTODSINTERVAL(5,'DAY'))
you should be able to this in current Oracle Releases: https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/ALTER-TABLE.html

Related

Oracle {LIST} Partition by Program and {RANGE} subpartition by DATE with interval

I'm trying to figure the best possible way to determine the partition strategy in Oracle 12c (12.2.0.1.0)
This post
is almost identical to my requirements. However, I want to know the best possible way to implement in Oracle 12c (12.2.0.1.0) version.
Here is my question:
We have four (4) distinct programs for which the bills are submitted in our system.
The approx volume of bills submitted per year is as follows:
Program_1 ~ 3M per year
Program_2 ~ 1M per year
Program_3 ~ 500K per year
Program_4 ~ 100K per year
My initial thought process is to create PARTITION BY LIST (PROGRAM) AND SUBPARTITION BY RANGE (BILL_SUBMISSION_DATE).
I would like to use oracle interval feature for SUBPARTITION, would like to know if there are any limitations with this approach.
Your approach of partitioning by PROGRAM and sub-partitioning by BILL_SUBMISSTION_DATE sounds good.
I have not tested performance differences (I imagine they would be negligible), but for coding the INTERVAL option makes querying and maintenance easier in my opinion.
For the following example the table partition clause I used was:
partition by range (INVOICE_MONTH) interval (numtoyminterval(1, 'MONTH'))
Example query, using old style partition names, query a partition for an invoice for April 2012, assuming I created a partition named INV201204 for those invoices for that month:
select * from MARK_INV_HDR
partition ('INV201204');
And the same query, using INTERVAL automatically generated partitions:
select * from MARK_INV_HDR
where invoice_month = to_date('2012-04', 'yyyy-mm');
The advantage of the later query is I don't have to know the naming convention for the partitions.
To drop the oldest partition, one query and one DDL:
select to_char(min(invoice_month), 'dd-Mon-yyyy') as min_inv_dt from MARK_INV_HDR;
MIN_INV_DT
-----------
01-Apr-2012
alter table mark_inv_hdr
drop partition for (TO_DATE('01-Apr-2012', 'dd-Mon-yyyy'))
update global indexes;
EDIT:
Update: I forgot that you cannot use the INTERVAL clause on a sub-partition; thanks to user12283435 for the reminder. In looking more closely at the question, it appears that there is probably no need to partition on PROGRAM, so just a single partition by range on BILL_SUBMISSION_DATE with the INTERVAL clause should work fine.
When you have a small set of values like you do for PROGRAM, no obvious reason to partition on it. The typical example of partitioning by list given in Oracle documentation is list of regions, for a global call center, so that you can do batch reports and maintenance on certain regions after business hours, etc. You can have a global bit-mapped index on PROGRAM, if you don't do many updates, if you query criteria frequently includes just one PROGRAM. (Updating a column with a bit-mapped index will briefly lock the table.)

Partitions in Informatica / Oracle tables

In my project they talk about Informatica job to drop and the re-create 'weekly/monthly partitions' every time it runs. Does that mean that the weekly/monthly partitions need to be created in Informatica or Oracle tables?
Yes it means you need to have partitioned table , you can have range partition, in your case it can be daily/weekly/monthly partition. when you create new one , if older data is not required you can delete partition.
Informatica reference
Oracle reference

Oracle Row Access Statistics

Here is a problem i am trying to solve -
Scenario:
Oracle production database having a table with large number of rows(~700 million)
Accumulated over the period,say 10 years
Requirement:
Partition it, in such a way that one partition should have rows which are being accessed or updated over a "period of defined time" and another will have rows which are never retrieved or updated in that "defined period of time".
Now since this table has updated timestamp columns it is easy to find out rows that are updated.
So i want to know is there any in-built row level stats available which can give me this info about row access?
SCN could help, if you want to find row modification time.
Select scn_to_timestamp(ora_rowscn), t.* from my_table t;
Note: scn highly depends on table definition - i.e. it could be defined as row level or block level. Another thing, there is a limit to which the oracle save the scn to timestamp mappings.

How to change RANGE value in PARTITIONS BY Range Oracle

I have an existing table within the next script:
create table sales6
(
sales_id number,
sales_dt date
)
partition by range (sales_dt)
(
partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd'))
);
What I need is to change the partition range to add an interval like this :
interval (numtoyminterval(1,'MONTH'))
I know that the right way to do it is when you create the table, but the table already exists and there are lot of records stored.
Is there any way to achieve this in Oracle 11g? I tried to ALTER the table but is not working due to 00940. 00000 - "invalid ALTER command"
Hope you can help me.
PS: I've been reading the whole documentation of Oracle in this two links without luck:
https://docs.oracle.com/cd/E17952_01/refman-5.5-en/alter-table-partition-operations.html
https://docs.oracle.com/cd/E17952_01/refman-5.1-en/partitioning-management-range-list.html
You can change a range partitioned table to a interval partitioned table with this command :
ALTER TABLE X SET INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'));
You can change back to range partitioned table with this command :
ALTER TABLE X SET INTERVAL();
Interval partitioning is always a more preferable option to range partitioning if your partitions are always evenly created (in identical periods).
The commands are not resource intensive because you don't manipulate segments and data, you just tell Oracle to begin or stop creating new partitions if new data that is inserted in the table doesn't fit by partition key in any existing partition.

"Dynamic" partitions in oracle 11g

I have a log table with a lot of information.
I would like to partition it into two: first part is the logs from the past month, since they are commonly viewed. Second part is the logs from the rest of the year (Compressed).
My problem is that all the examples of partitions where "up until 1/1/2013", "more recent than 1/1/2013" - That is with fixed dates...
What I am looking for/expecting is a way to define a partition on the last month, so that when the day changes, the logs from 30 days ago, are "automatically" transferred to the compressed partition.
I guess I can create another table which is completley compressed and move info using JOBS, but I was hoping for a built-in solution.
Thank you.
I think you want interval partitions based on a date. This will automatically generate the partitions for you. For example, monthly partitions would be:
create table test_data (
created_date DATE default sysdate not null,
store_id NUMBER,
inventory_id NUMBER,
qty_sold NUMBER
)
PARTITION BY RANGE (created_date)
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
(
PARTITION part_01 values LESS THAN (TO_DATE('20130101','YYYYMMDD'))
)
As data is inserted, Oracle will put into the proper partition or create one if needed. The partition names will be a bit cryptic (SYS_xxxx), but you can use the "partition for" clause to grab only the month you want. For example:
select * from test_data partition for (to_date('20130101', 'YYYYMMDD'))
It is not possible to automatically transfer data to a compressed partition. You can, however, schedule a simple job to compress last month's partition at the beginning of every month with this statement:
ALTER TABLE some_table
MOVE PARTITION FOR (add_months(trunc(SYSDATE), -1)
COMPRESS;
If you wanted to stay with only two partitions: current month and archive for all past transactions you could also merge partitions with ALTER TABLE MERGE PARTITIONS, but as far as I'm concerned it would rebuild the whole archive partition, so I would discourage doing so and stay with storing each month in its separate partition.

Resources