Итак, у меня есть таблица, в которой события организованы в отдельные потоки. Каждый поток имеет идентификатор (stream_id), а события в потоке имеют следующий номер (sequence_number). События представляют собой строки (JSON).
mydb=# \d stream
Table "public.stream"
Column | Type | Collation | Nullable | Default
-------------------+-------------------------+-----------+----------+---------
stream_id | character varying(255) | | not null |
sequence_number | bigint | | not null |
event | character varying(2000) | | not null |
Indexes:
"stream_pkey" PRIMARY KEY, btree (stream_id, sequence_number)
Для целей тестирования я вставил в эту таблицу 5 000 000 записей.
Чтобы найти все уникальные идентификаторы stream_id, которые я использую выберите отличительный в первом столбце составного первичного ключа, и это займет 18 секунд:
mydb=# select distinct stream_id from stream;
stream_id
-------------------
site-6
site-1
site-3
site-9
site-7
site-2
site-0
site-5
site-8
site-4
site-x
(11 rows)
Time: 18070.055 ms (00:18.070)
В то же время, если я сделаю это вручную, я могу сделать это за секунду (обратите внимание, что уникальные значения первый столбец - очень маленькое число по сравнению с общим числом строк):
- сначала найдите самый маленький:
mydb=# select min(stream_id) from stream;
min
--------
site-0
(1 row)
Time: 31.231 ms
затем найдите следующий, более крупный, чем последний, и снова и снова ...:
mydb=# select stream_id from stream where stream_id>'site-0' order by stream_id limit 1;
stream_id
-------------------
site-1
(1 row)
Time: 22.506 ms
mydb=# select stream_id from stream where stream_id>'site-1' order by stream_id limit 1;
stream_id
-------------------
site-2
(1 row)
Time: 30.054 ms
mydb=# select stream_id from stream where stream_id>'site-2' order by stream_id limit 1;
stream_id
-------------------
site-3
(1 row)
Time: 15.362 ms
mydb=# select stream_id from stream where stream_id>'site-3' order by stream_id limit 1;
stream_id
-------------------
site-4
(1 row)
...
Итак, вопрос в том, существует ли способ оптимизировать отдельный запрос на выборку вместо ручного обхода индекса первичного ключа с помощью нескольких выборок?
EDIT1: обратите внимание, что эта отдельная таблица оптимизирована для последовательного добавления / извлечения событий в / из потоков и выполнение этих точных операций является наиболее важным.