I have a table that grows at a rate of about 250 million rows per year. The primary key is a timestamp and two numeric identifiers. The timestamp is not uniformly distributed over year but follows the same time distribution year after year. There are 12 other number columns in the table. The data is read-only after data ingest. The data should be kept perpetually; however, there is some motivation to purge older (perhaps 10 years) data. The table is currently not partitioned and query performance has been rolling off over the years and has become slow enough to negatively affect the work flow.
The queries are usually one of the following (in order of most to least frequent):
- A narrow time window (a few seconds) with a bounds on the numeric identifiers,
- A wide time window (at most a day) with a bounds on the numeric identifiers,
- A wide time window (at most a week) with bounds on one or more of the other columns,
- One or more years without bounds on the numeric identifiers to generate summary statistics (count, monthly average, etc)--this is done infrequently,
- Bounds on the two numeric identifiers and/or the other columns with no restriction on the timestamp--very rare.
Looking at the different partitioning options, it appears either a range or an interval approach makes the most sense. My thought is to have each year in a separate tablespace and three ways come to mind on how to manage the partitioning:
- A range only approach where each year a new tablespace is created the partition definition is changed to add the new range,
- An interval approach and alter the default tablespace each year, and
- An interval approach keeping the default tablespace the same (e.g. current) and move partitions out of the current to a previous calendar year tablespace (e.g. ts2023, ts2022, etc).
My priorities are (in order of highest to lowest priority):
- Query performance,
- Reliability and speed of data ingest, and
- Ease of maintenance (though ease probably contributes to data ingest reliability).
Option #3 strikes me as the most straightforward because it can be performed at any time after crossing into a new calendar year and data ingest would not need to be stopped.
I have also thought about subpartitioning on one of the numeric identifiers but I am not sure there is much benefit for 250 million rows per annual partition. Performance was more than fine for most queries when there was less than 1 billion rows. That said, the overhead of subpartitioning appears negligible with a possibility of a modest performance enhancement, so this might fall into a "why not" situation.
Any thoughts or suggestions?