Партиціонування ділить одну логічну таблицю на кілька фізичних частин за ключем: за діапазоном дат, за списком значень чи за хешем. Для застосунку це одна таблиця, а база сама розкладає рядки по частинах.
CREATE TABLE events (
id bigint GENERATED ALWAYS AS IDENTITY,
created_at timestamptz NOT NULL,
payload jsonb
) PARTITION BY RANGE (created_at);
CREATE TABLE events_2026_10 PARTITION OF events
FOR VALUES FROM ('2026-10-01') TO ('2026-11-01');
Коли це виправдано:
- Дані «старіють»: логи, події, метрики, де запити дивляться на останні тижні, а старе треба видаляти. Видалити місяць -
DROP TABLE events_2025_10(мить), а неDELETEмільйонів рядків з навантаженням на вакуум. - Запити майже завжди фільтрують за ключем партиціонування - тоді спрацьовує partition pruning: база читає лише потрібні частини.
- Таблиця настільки велика, що індекси не вміщаються в пам'ять, а обслуговування (вакуум, перебудова індексу) окремих частин значно легше.
Коли НЕ варто: таблиця на кілька мільйонів рядків, з якою добре справляються індекси. Партиціонування - не заміна індексам.
Обмеження й пастки:
- Запит без ключа партиціонування в умові читає всі частини - часто повільніше, ніж одна таблиця.
- Первинний ключ і унікальні обмеження мусять містити ключ партиціонування:
PRIMARY KEY (id, created_at). - Частини треба створювати заздалегідь (cron чи розширення
pg_partman), інакше вставка в майбутній місяць упаде - або потрапить уDEFAULT-партицію.
Партиціонування ≠ шардинг: частини живуть на одному сервері. Розподіл по серверах - окреме, набагато складніше рішення.