Налаштування партиціонування таблиць PostgreSQL (Range/List/Hash)
Уявіть: ваша таблиця events виросла до 2 мільярдів рядків. VACUUM тягнеться годинами, pg_dump створює 400-гігабайтний файл, а видалення старих даних через DELETE блокує запис на години — бізнес стогне. Наші клієнти приходять з такими болями, і ми вирішуємо їх за допомогою декларативного партиціонування — під ключ, від аудиту до підтримки. За 7+ років ми бачили сотні таблиць: у 90% випадків партиціонування вирішує проблему продуктивності без зміни коду. За нашими даними, правильно налаштоване партиціонування скорочує час запитів у 50 разів, а обсяг бекапів — на 70%. Один клієнт заощадив $15,000 на рік на зберіганні за рахунок архівації старих секцій.
Партиціонування — розбиття однієї великої таблиці на кілька фізичних секцій. Механізм вбудований у PostgreSQL з версії 10 і прискорює запити, спрощує управління даними, знижує навантаження на БД. У цій статті розберемо вибір типу секціонування, автоматизацію та міграцію з мінімальним простоєм. Ми забезпечуємо прозорий план робіт, фіксовані терміни та SLA. Досвід підтверджено 50+ успішними проектами.
Чому партиціонування прискорює запити?
Три ключові механізми:
- Partition pruning — планувальник виключає нерелевантні секції з плану, скорочуючи час сканування в 10–100 разів.
- Миттєве видалення даних —
DROP TABLEна секцію виконується за мілісекунди, не блокує таблицю і не роздуває WAL. - Паралельне обслуговування —
VACUUM,ANALYZEта бекапи можна виконувати на окремих секціях.
На таблиці 500 ГБ ми спостерігали прискорення запиту за тиждень з 30 секунд до 300 мс — у 100 разів. Видалення старого місяця через DROP замість DELETE виконується в 1000 разів швидше.
Як вибрати тип партиціонування?
Таблиця нижче допомагає зробити вибір:
| Тип | Ключ | Сценарій | Приклад |
|---|---|---|---|
| Range | Діапазон (дата, ID) | Часові ряди, логи | created_at |
| List | Список значень | Категоріальні дані | region, status |
| Hash | Хеш-функція | Рівномірний розподіл | user_id |
Range підходить для даних з природним порядком — логи, метрики, транзакції. List — для кінцевого набору категорій. Hash — коли потрібен рівномірний розкид, але немає очевидного ключа.
Range Partitioning: типовий кейс для часових даних
-- Батьківська таблиця
CREATE TABLE events (
id BIGSERIAL,
created_at TIMESTAMPTZ NOT NULL,
user_id BIGINT NOT NULL,
event_type VARCHAR(64) NOT NULL,
payload JSONB
) PARTITION BY RANGE (created_at);
-- Створення партицій (вручну або через pg_partman)
CREATE TABLE events_2024_01 PARTITION OF events FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');Індекс на батьківській таблиці автоматично створюється на всіх секціях:
CREATE INDEX ON events (created_at, user_id); Автоматизація з pg_partman
Створювати партиції вручну — не наш метод. Використовуємо pg_partman:
SELECT partman.create_parent(
p_parent_table => 'public.events',
p_control => 'created_at',
p_type => 'range',
p_interval => 'monthly',
p_premake => 3
);
-- Налаштування видалення через 2 роки
UPDATE partman.part_config
SET retention = '2 years',
retention_keep_table = false
WHERE parent_table = 'public.events';
-- Запуск обслуговування (можна через pg_cron)
SELECT partman.run_maintenance();
Як працює partition pruning?
Partition pruning — оптимізація планувальника PostgreSQL: він виключає з плану секції, які не потрапляють в умову `WHERE` за ключем партиціонування. Щоб pruning працював, умова повинна містити ключ. Наприклад, `WHERE created_at >= '2024-01-01' AND created_at < '2024-02-01'` відсіче всі місяці, крім January 2024. Це скорочує обсяг сканованих даних на порядки.Hash Partitioning: рівномірний розподіл
Зазначимо: коли немає явного ключа, використовуємо хеш:
CREATE TABLE user_sessions (
id UUID DEFAULT gen_random_uuid(),
user_id BIGINT NOT NULL,
data JSONB,
expires_at TIMESTAMPTZ
) PARTITION BY HASH (user_id);
CREATE TABLE user_sessions_p0 PARTITION OF user_sessions FOR VALUES WITH (MODULUS 4, REMAINDER 0); Кейс із нашої практики: міграція таблиці логів на 500 GB
Клієнт — фінтех-платформа — зіткнувся з деградацією: запити за останніми логами виконувалися >30 секунд, VACUUM забивав I/O. Ми провели аудит, обрали Range по created_at з місячними секціями та pg_partman.
Процес міграції:
- Створили нову партиціоновану таблицю
logs_new. - Налаштували логічну реплікацію через pglogical для синхронізації.
- Скопіювали старі дані батчами по 10 млн рядків.
- Переключили застосунок на
logs_new(downtime — 2 хвилини).
Результат: запити за тиждень — 300 мс замість 30 секунд, видалення застарілих даних — миттєвий DROP, навантаження на VACUOM впало в 5 разів. Це дозволило заощадити на зберіганні за рахунок архівації старих секцій до 60%. Якщо ви зіткнулися з подібною проблемою, не відкладайте — замовте аудит та налаштування партиціонування вже сьогодні.
Як мігрувати таблицю без простою?
Міграція існуючої таблиці на партиціонування — найвідповідальніший етап. Ми використовуємо комбінацію pg_partman та логічної реплікації. Стандартний підхід: створити нову партиціоновану таблицю, синхронізувати дані через pglogical, скопіювати старі дані батчами, переключити застосунок. Для таблиць понад 1 ТБ рекомендуємо потокову реплікацію з тимчасовою зупинкою запису. У будь-якому випадку ми мінімізуємо downtime до кількох хвилин. Отримайте консультацію та розрахунок термінів — зв'яжіться з нами.
Що входить у нашу роботу
- Аудит таблиць-кандидатів (розмір, патерни доступу, типи запитів).
- Вибір стратегії партиціонування (тип, ключ, інтервал).
- Розробка схеми секцій та автоматизації (pg_partman + cron).
- Налаштування partition pruning та моніторинг продуктивності.
- Міграція існуючих таблиць з мінімальним downtime.
- Документація, навчання команди та post-deploy супровід.
Гарантуємо прозорий план робіт, фіксовані терміни та SLA на підтримку. Наш досвід — 7+ років у PostgreSQL, 50+ успішних проектів.
Процес роботи
- Аналітика — збір метрик, виявлення вузьких місць, оцінка обсягів.
- Проектування — вибір типу партиціонування, проектування схеми.
- Реалізація — написання міграційних скриптів, налаштування автоматизації.
- Тестування — перевірка partition pruning, порівняння продуктивності на staging.
- Деплой — виконання міграції в production, моніторинг.
Терміни орієнтовно
| Обсяг даних | Час (робочі дні) |
|---|---|
| Нова таблиця | від 2 днів |
| Існуюча таблиця до 100 GB | від 5 днів |
| Таблиця 100+ GB з тестуванням | до 2 тижнів |
Вартість розраховується індивідуально — напишіть нам, оцінимо ваш проект за 1-2 дні. Зв'яжіться з нами — допоможемо розібратися з партиціонуванням та прискорити вашу БД.







