Как выделить отчетливый первый столбец составного первичного ключа в PostgreSQL? - PullRequest
0 голосов
/ 23 апреля 2020

Итак, у меня есть таблица, в которой события организованы в отдельные потоки. Каждый поток имеет идентификатор (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)

В то же время, если я сделаю это вручную, я могу сделать это за секунду (обратите внимание, что уникальные значения первый столбец - очень маленькое число по сравнению с общим числом строк):

  1. сначала найдите самый маленький:
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: обратите внимание, что эта отдельная таблица оптимизирована для последовательного добавления / извлечения событий в / из потоков и выполнение этих точных операций является наиболее важным.

1 Ответ

0 голосов
/ 23 апреля 2020

Может разделить данные, поэтому получение StreamId также не извлекает документы JSON. Например, три таблицы:

  1. Уникальный идентификатор 1 + StreamId
  2. Уникальный идентификатор 2 + JSONDocument
  3. Уникальный идентификатор 1 + Уникальный идентификатор 2 + Порядковый номер: таблица соответствия между их

Больше усилий для работы, но вы не получите данные документа JSON, когда они вам не нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...