Make id
the leading column:
PRIMARY KEY (id, created_at)
The rule of thumb is: equality first, range later. See:
Related:
Also, since ...
It is a single table that won't be partitioned and all of the rows are insert only, no updates will ever occur.
It will be beneficial to CLUSTER
the table on the PK index from time to time. CLUSTER
rewrites the table according to index order and takes an exclusive lock. So only an option if there are maintenance windows allowing that. Else, look to the community tools pg_repack
or pg_squeeze
, which can do the same non-blocking. See:
Postgres has to read a minimum of data pages from a table freshly clustered like that. The effect is small for very selective queries, where index performance dominates, but grows with the number of qualifying rows. (CLUSTER
and the community tool also rewrite the index in pristine condition.)
Finally, do you really need SELECT *
? SELECT id, created_at
could be (mostly) served from the index directly with an index-only scan - if you vacuum the table enough.
Aside: always use the recommended ISO date-format, which is unambiguous with any locale setting. '2022-03-02' (or '2022-3-2'), not '3/2/2022'.