deшка
Урок 11.5

Партиции и отсечение данных

Логические части таблицы, границы периодов и pruning; отличие от размещения по сегментам.

Распределение делит строки между сегментами для параллельной работы. Партиционирование делит таблицу на логические части по правилу, например по месяцу. Эти решения применяются одновременно: данные каждого месяца могут храниться на всех сегментах.

Родитель и части таблицы

Партиционированная таблица объединяет дочерние части через общего родителя. Пользователь обращается к общему имени, а строка относится к подходящей части по значению ключа партиционирования. В Greenplum 7 используется декларативное партиционирование, основанное на PostgreSQL 12.

Для диапазонов задают границы: январь, февраль, март. Для списков — наборы конкретных значений. Можно строить несколько уровней, но у каждой дополнительной части есть метаданные и работа при планировании и обслуживании. Тысячи мелких частей не становятся полезными только потому, что таблица большая.

Из трёх месячных частей условие по февралю оставляет только февраль; январь и март исключаются

На рисунке запросу нужен февраль. Если планировщик может сопоставить фильтр с границами, январь и март не нужно читать. Это называется partition pruning, отсечение партиций. В зависимости от плана ненужные части могут исключаться при планировании или во время выполнения.

Что именно отсекает pruning

Простой диапазон по колонке партиционирования помогает доказать, что часть не подходит. Для февраля условие от 1 февраля включительно до 1 марта исключительно совпадает с месячными границами. Отсечение экономит чтение целых частей, прежде чем начнётся обработка их строк.

Если фильтра по дате нет, одинаковое имя родителя не делает чтение дешевле: запросу могут понадобиться все месяцы. Фильтр по другой колонке также сам по себе не исключает месячные части. А сложное выражение над датой может оказаться труднее сопоставить с границами, чем обычное сравнение.

Проверяют pruning по плану: какие дочерние части остались в сканировании и какие выбираются динамически. У разных оптимизаторов вывод различается. Число партиций в каталоге ещё не говорит, сколько из них прочитал конкретный запрос.

Границы без перекрытий

Для времени удобны полуоткрытые интервалы: нижняя граница включена, верхняя исключена. Тогда момент начала марта принадлежит марту и не пересекается с февралем. Не приходится подбирать «последнюю секунду месяца», особенно для timestamp с дробной частью.

Короткий пример DDL для Greenplum 7 показывает независимость двух ключей:

Greenplum 7: месяц и ключ распределения
CREATE TABLE measurements (
    record_id bigint,
    event_date date,
    value numeric
) DISTRIBUTED BY (record_id)
PARTITION BY RANGE (event_date);
 
CREATE TABLE measurements_feb PARTITION OF measurements
FOR VALUES FROM ('2026-02-01') TO ('2026-03-01');

Здесь event_date выбирает логическую часть, а record_id — сегмент. До создания других частей строки с датами вне февраля не имеют подходящего места и при вставке вызовут ошибку. Родитель описывает общую структуру, а данные находятся в листовых частях.

Default partition принимает значения, которым не подошла другая часть. Она может быть полезна для контроля неожиданных дат, но её нужно наблюдать и разбирать. Pruning способен исключить и default, когда ограничения доказывают, что нужные строки находятся в другом месте; правило «default читается всегда» неверно.

При добавлении нового диапазона проверяют, нет ли соответствующих строк уже в default. Проверки, перенос данных и блокировки зависят от операции. В старом синтаксисе Greenplum 6 команды управления частями выглядят иначе, поэтому их не смешивают механически с PARTITION OF.

Партиция не равна сегменту

На каждом из трёх сегментов есть январская и февральская части одной таблицы

У месячной таблицы февраль не «переезжает на отдельную машину». Внутри каждой части строки распределяются по принятой политике. Отсечение января уменьшает объём работы всех сегментов, а удачный distribution key помогает равномерно выполнить оставшуюся работу и соединить данные.

Поэтому партиционирование по дате не исправляет неудачное распределение по часто повторяющемуся ключу. И наоборот, равномерная дистрибуция не освобождает от чтения ненужных месяцев, если фильтр не использует границы. Это две разные причины лишней работы.

Загрузка и срок хранения

Логическая часть полезна не только для запросов. Период можно подготовить отдельно, проверить и затем подключить, а устаревшую часть — отключить или удалить по процедуре хранения данных. Это позволяет работать с крупным законченным набором вместо множества построчных удалений.

Такие операции всё равно требуют проверки совместимости структуры, ограничений, распределения и блокировок. Отключённая таблица может продолжать занимать место. Удаление части меняет доступные данные. Поэтому в рабочем хранилище заранее определяют порядок публикации периода и возможность отката.

Шаг партиционирования выбирают по двум вопросам: какой диапазон обычно читают и какой объём удобно загружать или удалять целиком. Месяц — понятный пример, но не универсальный ответ. Если большинство запросов читают всю историю, главное преимущество частей может оказаться в обслуживании, а не в скорости чтения.

Войти, чтобы отмечатьдальше →
11.6 →Виды таблиц в Greenplum