Настройка 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, нагрузка на VACUUM упала в 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