PostgreSQL 14 RC: бенчмаркируем прирост производительности на партиционированных DWH-схемах
PostgreSQL 14 Release Candidate - тестируем declarative partitioning и vacuum на продуктовой схеме клиента. Прирост 15-20% на сложных запросах с partition pruning.
PostgreSQL 14 Release Candidate выходит с значительным ускорением declarative partitioning и улучшениями vacuum
PostgreSQL 14 дошёл до Release Candidate. Это означает: фичи заморожены, идут только исправления, релиз вот-вот. Мы взяли RC и прогнали его на стенде с клиентской DWH-схемой, которую последние полгода держим на PG13. Итоги неплохие - рассказываем что мерили и зачем это вообще было нужно.
Зачем мерить на RC, не ждать GA
Логика простая. Клиент планирует апгрейд в конце года, и нам нужен обоснованный ответ на вопрос «а что мы получим». Маркетинговые release notes с формулировкой «значительное ускорение партиционирования» - это хорошо, но не достаточно. Клиентская схема конкретная: несколько сотен миллионов строк, партиционирование по дате (monthly partitions), аналитические запросы с агрегацией по нескольким измерениям. Что значит «значительное» именно на ней - надо смотреть самим.
RC в этом смысле уже представителен: core optimizer и executor в нём финальные. Если прирост есть - он будет и в GA. Если нет - тоже знать полезно заранее.
Стенд и схема
Восстановили слепок продуктовой базы на отдельный хост, поставили туда же PG13 и PG14 RC в разные кластеры (один порт / один хост через разные data directories и порты). Данные одинаковые, конфигурация postgresql.conf - максимально близкая: shared_buffers, work_mem, max_parallel_workers_per_gather выровнены.
Схема примерно такая:
CREATE TABLE events (
id bigint NOT NULL,
occurred_at timestamp NOT NULL,
account_id integer NOT NULL,
event_type text NOT NULL,
amount numeric(18,4),
region_id smallint NOT NULL
) PARTITION BY RANGE (occurred_at);
-- партиции вида events_2019_01, events_2019_02, ...
-- на момент теста - около 32 партиций
Индексы на (occurred_at, account_id) и (account_id, event_type) на каждой партиции. Типичный аналитический запрос - агрегация по account_id с фильтром по периоду и типу события.
Что и как мерили
Запускали три класса запросов, каждый по 10 итераций с EXPLAIN (ANALYZE, BUFFERS), первые две итерации выбрасывали как прогрев кеша. Смотрели на Planning Time и Execution Time отдельно.
Запросы с узким partition pruning - фильтр по конкретному месяцу или кварталу. Оптимизатор должен отсечь лишние партиции на этапе планирования. Здесь прирост оказался наиболее заметным: Planning Time на сложных запросах с несколькими join'ами снизился ощутимо. В PG13 планировщик на некоторых запросах тратил больше времени просто на перебор партиций при планировании, в PG14 это стало быстрее.
Запросы с широким сканом - агрегация за два-три года без жёсткого фильтра по дате. Здесь партиций много, pruning даёт меньше, запрос всё равно идёт в параллель по нескольким partitions. Прирост здесь скромнее - в пределах погрешности измерений.
Запросы с динамическим pruning - фильтр по параметру, который оптимизатор не может разрешить статически (приходит из подзапроса). PG14 улучшил именно динамический pruning, и здесь разница наиболее интересная: запросы, которые в PG13 сканировали все партиции потому что не могли разрешить фильтр на этапе плана, в PG14 правильно режут партиции на этапе выполнения.
Суммарно по первому и третьему классам - прирост в районе 15-20% по Execution Time на самых нагруженных запросах. Это не синтетика, это реальные запросы из клиентского приложения.
Vacuum и autovacuum: что изменилось
В PG14 autovacuum стал более агрессивным в отношении «раздутых» страниц. Конкретно - появился механизм vacuum_failsafe_age, который форсирует vacuum при приближении к опасному transaction ID wraparound, не дожидаясь обычного расписания.
На нашем стенде это менее критично, чем на OLTP: DWH с аналитической нагрузкой не генерирует такое количество мёртвых строк как продуктовая OLTP. Но у клиента есть staging-область куда заливаются сырые данные, активно обновляются и потом переносятся в основные таблицы. Вот там bloat периодически был проблемой. Новое поведение vacuum смотрим отдельно.
Что не тестировали на RC
Logical replication с row-level filtering мы смотрели ещё на Beta 3 - там поведение не изменилось, работает как ожидается. JSON/SQL Path улучшения в RC тоже не трогали - это не критично для данного клиента.
Готовим план миграции
По итогам стенда у нас есть конкретный ответ: на этой схеме переход с PG13 на PG14 даёт реальное ускорение на наиболее частых аналитических запросах. Не «могло бы дать», а «дало на тестовых данных, идентичных продуктовым».
Для клиента это означает: апгрейд обоснован не только «новая версия - хорошо», но и измеримым улучшением. Что важно - сама миграция не требует изменений схемы. Partition strategy остаётся той же, индексы те же, приложение трогать не нужно. Это in-place upgrade через pg_upgrade или резервная схема с параллельным кластером.
Конкретный срок апгрейда - после выхода GA и первого patch release. На RC в продакшн не идём принципиально: RC это не GA, и без первого фикса после релиза прод-разворачивание выглядит как лишний риск.
Работы по миграции и поддержке DWH-инфраструктуры ведём в рамках DWH и бизнес-аналитики.