(в первую очередь - извиняюсь за название, но лучше не придумал)
Вот моя проблема - у меня есть таблица с 4 столбцами - entity::INT
, entry::TEXT
, state::INT
и day::INT
.
Может быть от 50 до 1000 entities
. Каждый entity
может иметь более 100 миллионов entries
. Каждый entry
может иметь один или несколько states
, который изменяется, если данные, хранящиеся в записи, изменились, но только один state
может быть записан для любого конкретного day
. day
начинается с единицы и увеличивается каждый день.
Пример:
entity | entry | state | day
-------------------------------------
1 | ABC123 | 1 | 1
1 | ABC124 | 2 | 1
1 | ABC125 | 3 | 1
...
1 | ABC999 | 999 | 1
2 | BCD123 | 1000 | 1
...
1 | ABC123 | 1001 | 2
2 | BCD123 | 1002 | 3
Индекс установлен на (entity, day, state)
.
Чего я хочу достичь заключается в эффективном выборе наиболее актуального состояния каждой записи в день N.
В настоящее время каждую неделю я записываю все записи с их последними state
в таблицу, чтобы минимизировать количество дней, которые нам нужно сканировать, однако, учитывая общее количество entries
(наихудший сценарий - 1000 сущностей умножить на 100000000 записей - это много строк, которые нужно записывать каждую неделю), таблица медленно, но верно раздувается, и все становится очень медленно .
Мне нужно прекратить писать эту «полную» версию еженедельно и вместо этого иметь достаточно быструю настройку для этого. Я решил использовать DISTINCT ON
с другим индексом, установленным на (entity, entry, day DESC, state)
, чтобы я мог:
SELECT DISTINCT ON (entity, entry) entry, state
FROM table
WHERE entity = <entity> AND day <= <day>
ORDER BY entity, entry, day DESC, state;
Будет ли это наиболее эффективным способом сделать это или есть способы лучше? Или entry
, возможно, имеющий сотни миллионов уникальных значений, делает его плохим выбором для второго столбца в индексе, и производительность в конечном итоге остановится?