Skip to content
Advertisement

Optimize performance for queries on recent rows of a large table

I have a large table:

90% of all requests are about orders from the last 2-3 days by a person_id, like:

How can I improve performance?

I know about Partitioning, but what about existing rows? And it looks like I need to create INHERITS tables manually every 2-3 days.

Advertisement

Answer

A partial, multicolumn index on (person_id, created) with a pseudo-IMMUTABLE condition would help (a lot). Needs to be recreated from time to time to keep performance up.

Note, if your table is not very big, you can largely simplify and use a plain multicolumn index.
Or consider table partitioning in Postgres 12 or later (where the feature finally matured).

A primitive function provides a constant point in time, 3 or more days back (represented by a unix epoch in your case):

PARALLEL SAFE only for Postgres 10 or later.
1387497600 being the result of:

Base your partial index on this pseudo-IMMUTABLE condition:

Base your query on the same condition:

The line AND created >= f_orders_idx_start() seems redundant, but is instrumental to convince Postgres to use the partial index.

A function to recreate function and index from time to time. Possibly with a cron-job every night:

Then, to rebase your index, call (ideally with little or no concurrent load):

If you cannot afford dropping and recreating the index due to concurrent load, consider REINDEX CONCURRENTLY in Postgres 12 or later. It’s dead simple:

All queries continue to work, even if you never call this function. Performance slowly deteriorates over time with the growing partial index.

I am using this regime successfully with a couple of big tables and similar requirements. Very fast.

For Postgres 9.2 or later, and if your table has only few, small columns, and if the table is not heavily written, it might pay to make that a covering index:

In Postgres 11 or later, you might want to use INCLUDE instead:

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement