Налаштування партиціонування таблиць PostgreSQL (Range/List/Hash)

Ваші таблиці розрослися, запити сповільнюються, а обслуговування бази перетворюється на рутину? Ми налаштовуємо декларативне партиціонування PostgreSQL (Range/List/Hash), щоб повернути швидкість і керованість. Наша команда реалізує проєкт під ключ — від аудиту до впровадження та подальшої підтримки, забезпечуючи стабільну роботу без зриву термінів.
Часті запитання

Налаштування партиціонування таблиць 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.

Процес міграції:

  1. Створили нову партиціоновану таблицю logs_new.
  2. Налаштували логічну реплікацію через pglogical для синхронізації.
  3. Скопіювали старі дані батчами по 10 млн рядків.
  4. Переключили застосунок на 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+ успішних проектів.

Процес роботи

  1. Аналітика — збір метрик, виявлення вузьких місць, оцінка обсягів.
  2. Проектування — вибір типу партиціонування, проектування схеми.
  3. Реалізація — написання міграційних скриптів, налаштування автоматизації.
  4. Тестування — перевірка partition pruning, порівняння продуктивності на staging.
  5. Деплой — виконання міграції в production, моніторинг.

Терміни орієнтовно

Обсяг даних Час (робочі дні)
Нова таблиця від 2 днів
Існуюча таблиця до 100 GB від 5 днів
Таблиця 100+ GB з тестуванням до 2 тижнів

Вартість розраховується індивідуально — напишіть нам, оцінимо ваш проект за 1-2 дні. Зв'яжіться з нами — допоможемо розібратися з партиціонуванням та прискорити вашу БД.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139