Партиционирование таблиц БД: ускорение запросов и управление данными
Мы реализуем партиционирование таблиц баз данных. Проблема роста данных — одна из самых частых причин падения скорости. На прошлом проекте у клиента таблица events выросла до 500 млн строк, запросы висели по 30 секунд. Мы внедрили партиционирование по месяцам — время отклика упало до 50 мс, а стоимость хранения снизилась на 40% за счет архивации старых разделов.
На другом проекте таблица логов занимала 1.5 ТБ, после разделения по дням активный набор сократился до 50 ГБ, а TTFB упал с 3 секунд до 200 мс. Без партиционирования каждый SELECT сканирует всю таблицу, растут LCP и INP. Partition pruning отсекает ненужные разделы, ускоряя запросы в 5–20 раз в зависимости от селективности. Типичная выборка за последний месяц при range-разбиении по дате выполняется в 10 раз быстрее полного сканирования.
Наши инженеры имеют 10+ лет опыта в оптимизации баз данных и успешно реализовали более 50 проектов с партиционированием. Мы гарантируем корректную работу решения.
Какие проблемы решает партиционирование таблиц?
- Падение скорости: большие таблицы без партиционирования сканируют всё, растут LCP и TTFB. Запросы с фильтром по дате или категории — самые частые жертвы.
- Трудности с обслуживанием: очистка или архивация старых данных превращается в мучительное DELETE с блокировками.
- Высокие затраты на хранение: SSD дорог, а хранить всю историю на быстром диске нерационально.
Как мы внедряем партиционирование таблиц
Стек и инструменты
| Компонент | Инструменты |
|---|---|
| СУБД | PostgreSQL (10+), MySQL (8.0+) |
| Автоматизация | pg_partman, cron |
| Миграция | логическая репликация, батчи |
Типы партиционирования: сравнение
| Тип | Описание | Когда использовать |
|---|---|---|
| Range | По диапазонам значений (даты, числа) | Временные данные, логи, события |
| Hash | По хешу ключа | Равномерное распределение нагрузки, нет естественного деления |
| List | По списку значений (страны, статусы) | Фиксированные категории |
Конкретный кейс
Заказчик — маркетинговое агентство. Таблица событий — 500 млн строк, рост 10 млн в месяц. Запросы к статистике за последний год тормозили, бэкапы весили 200 ГБ.
Мы спроектировали range-партиционирование по created_at с месячными разделами. Подключили pg_partman: премейк 3 партиции вперед, retention 12 месяцев (автоудаление).
CREATE TABLE events ( id BIGSERIAL, user_id INTEGER NOT NULL, event_type VARCHAR(64) NOT NULL, payload JSONB, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ) PARTITION BY RANGE (created_at); CREATE TABLE events_2023_01 PARTITION OF events FOR VALUES FROM ('2023-01-01') TO ('2023-02-01'); -- pg_partman: создание расписания SELECT partman.create_parent( p_parent_table => 'public.events', p_control => 'created_at', p_type => 'native', p_interval => 'monthly', p_premake => 3 ); Результат: запросы ускорились в 10 раз, размер продакшена — только актуальные 6 месяцев, старые данные в объектном хранилище.
Почему важен правильный выбор ключа партиционирования?
Partition pruning срабатывает только когда WHERE явно использует ключ. Типичная ошибка — оборачивать ключ в функцию: DATE(created_at) = '2023-01-15' — pruning отключается. Правильно: created_at >= '2023-01-15' AND created_at < '2023-01-16'. Мы проверяем это при тестировании.
Как выполнить миграцию без простоя?
- Создаем новую партиционированную таблицу с тем же набором полей.
- Копируем данные батчами по месяцам (отдельные INSERT).
- Переключаем через транзакцию: ALTER TABLE events RENAME TO events_old; ALTER TABLE events_partitioned RENAME TO events; — секунды.
- Удаляем старую таблицу после недели мониторинга.
- Настраиваем pg_partman для автоматического управления.
Детальный план миграции
Копирование больших объемов без блокировок — используем логическую репликацию или pglogical. Процесс занимает от нескольких часов до суток в зависимости от размера данных. Мы проводим миграцию в рабочее время или в минимальное окно.
Процесс работы
- Аналитика — профилируем запросы, выявляем самые медленные, оцениваем объем данных и скорость роста.
- Проектирование — выбираем ключ и тип партиционирования (range, hash, list), число разделов.
- Реализация — пишем скрипты, настраиваем pg_partman, создаем исторические партиции.
- Тестирование — проверяем partition pruning, замеряем производительность до/после.
- Деплой — миграция по описанной схеме, в рабочее время или с минимальным окном.
- Мониторинг — настраиваем алерты на пропущенные партиции и превышение порогов.
Сроки и что входит
Ориентировочные сроки: от 3 до 10 рабочих дней. Стоимость рассчитывается индивидуально. Входит в работу:
- Документация схемы партиционирования
- Скрипты создания и управления партициями
- Настройка автоматического обслуживания (pg_partman или аналог)
- Инструкция по мониторингу и алертам
- Гарантия 3 месяца на корректную работу
Закажите консультацию по вашему проекту — мы проанализируем нагрузку и предложим оптимальное решение.
Типичные ошибки при партиционировании таблиц
- Неправильный ключ — pruning не работает, производительность падает
- Индексы созданы на родителе, но не на всех партициях (PG<11)
- Отсутствует премейк — новые партиции не создаются вовремя
- В MySQL уникальные ключи обязаны включать ключ партиционирования
Когда партиционирование не нужно
- Таблица меньше 10–20 млн строк — достаточно индексов
- Нет четкого ключа (данные без временной или категориальной метки)
- Запросы не фильтруют по ключу — выгоды не будет
Подробнее о партиционировании PostgreSQL — официальная документация
Свяжитесь с нами для бесплатной оценки вашего проекта. Мы проанализируем нагрузку и предложим оптимальное решение.







