Skip to Main Content
  • Questions
  • Local or Global index on Primary key of Petitioned table

Breadcrumb

XMAS_TREE

The AskTOM team is taking a break over the holiday season, so we're not taking questions or responding to comments, but we might still sneak in a few Office Hours sessions! Thanks for being a member of the AskTOM community.

Question and Answer

Connor McDonald

Thanks for the question, Fahd.

Asked: July 31, 2024 - 12:19 pm UTC

Last updated: August 19, 2024 - 2:26 am UTC

Version: 19c

Viewed 1000+ times

You Asked

Hi Team,

i want to create a table with monthly partition on it so that i can make purging easy by dropping partitions that are not needed. i also want to avoid rebuild of primary key index after dropping partition, how to do it ?
can primary key index be local ?

following is create table statement

CREATE TABLE large_table (
    auto_id         NUMBER GENERATED AS IDENTITY (START WITH 1 MAXVALUE 9999999999999999999999999999 MINVALUE 1 NOCYCLE CACHE 20 NOORDER NOKEEP) NOT NULL,
    tran_id         NUMBER,
    created         TIMESTAMP(6) DEFAULT systimestamp,
    CONSTRAINT large_table_hits_pk PRIMARY KEY (auto_id)
)
PARTITION BY RANGE (created)
INTERVAL (INTERVAL '1' MONTH)
(
    PARTITION p0 VALUES LESS THAN (TO_DATE('2024-07-01', 'YYYY-MM-DD'))
);

and Connor said...

Yes you can, but requires a compromise. You need to add CREATED as a column in the primary key, eg

SQL> CREATE TABLE large_table (
  2      auto_id         NUMBER GENERATED AS IDENTITY NOT NULL,
  3      tran_id         NUMBER,
  4      created         TIMESTAMP(6) DEFAULT systimestamp,
  5      CONSTRAINT large_table_hits_pk PRIMARY KEY (auto_id,created) using index local
  6  )
  7  PARTITION BY RANGE (created)
  8  INTERVAL (INTERVAL '1' MONTH)
  9  (
 10      PARTITION p0 VALUES LESS THAN (TO_DATE('2024-07-01', 'YYYY-MM-DD'))
 11  );

Table created.


This obviously has implications for your applications in how they access the data, what keys they store etc etc, but it can be done.

Another option I've seen used, is a secondary table, because your LARGE_TABLE above is more likely to be

CREATE TABLE large_table (
    auto_id         NUMBER GENERATED AS IDENTITY NOT NULL,
    tran_id         NUMBER,
    created         TIMESTAMP(6) DEFAULT systimestamp,
    ..
    ..
    .. LOTS OF OTHER COLUMNS
    ..
    ..
    CONSTRAINT large_table_hits_pk PRIMARY KEY (auto_id,created) using index local
)
PARTITION BY RANGE (created)
INTERVAL (INTERVAL '1' MONTH)
(
    PARTITION p0 VALUES LESS THAN (TO_DATE('2024-07-01', 'YYYY-MM-DD'))
);



An additional table could be just:

create table LARGE_KEYS
auto_id number,
created timestamp(6),
constraint LARGE_KEYS_PK primary key ( auto_id)
)
organization index;


This table is non-partitioned but never needs archiving - its the link between and ID and its CREATED time.

Thus your apps just need to ID as per normal. The ID uses LARGE_KEYS to get the CREATED value, which is then used to mine into LARGE_TABLE for the rest of the data.


Rating

  (2 ratings)

We're not taking comments currently, so please try again later if you want to add a comment.

Comments

A reader, August 07, 2024 - 11:26 am UTC

okay, Thanks Connor

Asynchronous global index maintanence

Rajeshwaran, Jeyabal, August 12, 2024 - 2:58 pm UTC

How about Async global index maintenance

https://docs.oracle.com/en/database/oracle/oracle-database/19/vldbg/maintenance-partition-can-be-performed.html#GUID-087B87A6-959A-40C6-82AF-36E401FD089B

So that the drop partition will be still instantaneous, but later a background job will take care of cleaning up those orphaned index entries.

Connor McDonald
August 19, 2024 - 2:26 am UTC

We covered this on an Office Hours session recently


More to Explore

VLDB

If you are new to partitioning, check out Connor McDonald's introduction series here.

VLDB

Documentation set on VLDB and Partitioning.