Представьте себе таблицу вроде ...
create table study_value (
id serial primary key,
study_id int not null references study (id),
category text not null,
subcategory int not null,
p_value double precision not null
);
Я знал, что в ней будет 25+ миллионов строк, и они должны быть быстро запрошены родительским исследованием, а также, необязательно, по категории и подкатегории, поэтому я решил добавить к нему BRIN.
create index study_value_idx
on study_value using brin (study_id, category, subcategory);
Все данные для данного исследования (1 миллион + строк) были вставлены в массовом порядке (упорядочены по категориям / подкатегориям) из буфера через ...
copy study_value from stdin with (format csv, header false);
Данные этого исследования были загружены последовательно в порядке идентификаторов исследования, поэтому порядок вставки полностью соответствовал порядку столбцов BRIN.
Проблема, с которой я сталкиваюсь, заключается в том, что запрашивает эту таблицу при условиях, которым удовлетворяет BRIN, например. select count(*) from study_value where study_id = 3;
, выполняет полное сканирование и занимает более 30 секунд. Размер самого BRIN составляет 48 кб.
Однако если я reindex index study_value_idx
, запросы теперь занимают ~ 100 мс, а размер индекса превышает 100 кб.
Все, что я читал (в документации PG, на SO, et c.) указывает, что нужно только переиндексировать в очень специфических c ситуациях (например, повреждение данных или невозможность построения индексов).
Мне не нужно было отбрасывать индекс перед загрузкой данных и заново создавать его после этого, потому что копирование 1 миллиона записей в таблицу заняло всего 10 секунд.
Я что-то делаю не так? Есть ли лучший способ сделать это?
Изменить:
Я забыл упомянуть, что до запуска reindex я запускал analyze study_value
и не видел изменений.