Индекс BRIN в PostgreSQL хранит только min и max колонки на диапазон страниц и весит килобайты, что удобно для логов и событий. Инженер, делавший такие же zonemaps в Oracle, измерил на 10 млн строк, что с BRIN делают обычные
UPDATE. Ломается он тихо.Свежий BRIN по
created_at весит 48 КБ против 214 МБ у B-tree и отдаёт день за 21,2 мс (1536 страниц). После обновления 5 % строк тот же запрос читает 51 268 страниц и идёт 558,7 мс: 3,8 млн строк достаются и отбрасываются проверкой.Причина в MVCC:
UPDATE кладёт новую версию строки туда, где есть место. Одна январская строка в «мартовском» диапазоне из 128 страниц расширяет его min/max, и он совпадает с любым январским запросом. А pg_stats.correlation ещё показывает 0,921.Проверьте у себя: в
EXPLAIN (ANALYZE, BUFFERS) смотрите на Heap Blocks: lossy, корреляция ничего не покажет. Лечит CLUSTER, но с блокировкой таблицы. Скрипт есть в статье.#postgresql #sql
