P
P
parallel47adm2022-04-06 13:41:00
PostgreSQL
parallel47adm, 2022-04-06 13:41:00

How to make a proper complex index?

There is a rather large table (200M+) that has three columns of interest:
update_date timestamptz
num_status int
n_flag int

n_flag can be 0..5
num_status 0..20
update_date is when the record was updated.

We need to find the oldest record, where n_flag=0 and num_status>=10.

Query
select * from table1 where n_flag=0 and num_status>=10 order by update_date asc limit 1;
Very long time.

select * from table1 where num_status>=10 order by update_date asc limit 1; - quickly
select * from table1 where n_flag=0 order by update_date asc limit 1; - fast

All three fields have an index.
How to do it right?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Melkij, 2022-04-06
@parallel47adm

We need to find the oldest record, where n_flag=0 and num_status>=10.

btree(update_date) where n_flag=0 and num_status>=10

A
Akina, 2022-04-06
@Akina

n_flag can be 0..5
num_status 0..20
...
entry where n_flag=0 and num_status>=10.

The specified conditions with a uniform distribution of values ​​correspond to ~9% of records, i.e. 18 million. Moreover, the selection by n_flag is more selective.
Purely theoretically optimal without using Postgress features will be the index (n_flag, update_date, num_status).
DEMO fiddle . True, I somehow did not dare to generate 200 million records ... but for 1 million records, the query shows 40-50 ms - in my opinion, sane.
PS. The index is called "complex", but composite. In addition, this index is covering, i.e. the server does not need to access the table to process the request.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question