Настройка 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, нагрузка на VACUUM упала в 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 дня. Свяжитесь с нами — поможем разобраться с партиционированием и ускорить вашу БД.







