deшка
Урок 11.4

JOIN и перемещение данных

Где встречаются строки: локальный JOIN, Redistribute, Broadcast и сбор результата через Gather.

Для JOIN исполнитель должен увидеть обе стороны подходящей пары. Если одна строка хранится на сегменте 0, а её пара на сегменте 1, локальный оператор соединения не получит их вместе. Greenplum решает это через план: сохраняет подходящее размещение или перемещает строки между исполнителями.

Локальное соединение

Локальный JOIN возможен, когда необходимые пары уже доступны одному сегменту. Пусть таблицы L и R распределены совместимо по ключу k, а соединение использует равенство L.k = R.k. В условной раскладке ключ A хранится на сегменте 0 в обеих таблицах, B — на сегменте 1. Каждый сегмент может соединить свои строки без обмена между ними.

На каждом сегменте строки L и R с одинаковым ключом соединяются на месте

Для такой гарантии недостаточно одинаковых названий колонок. Нужны совместимые типы и хеширование, политики распределения и набор сегментов. Если ключ составной, соединение должно обеспечивать равенство по его полному набору. Приведение типа или выражение над ключом также могут помешать использовать исходное размещение.

Локальность относится к конкретному этапу. Даже если JOIN обошёлся без пересылки, итоговая сортировка или группировка может потребовать Motion. Также локальный JOIN не обещает равномерную работу: частый ключ способен создать много совпадений на одном сегменте.

Redistribute: собрать одинаковые ключи вместе

Redistribute Motion заново распределяет поток строк по хешу ключа, нужного следующей операции. В примере L исходно размещена по другой колонке: строка A находится на сегменте 1, B — на сегменте 0. R уже распределена по ключу соединения. План пересылает строки L так, чтобы A и B встретились со своими парами.

Строка L с A переходит с сегмента 1 на сегмент 0, строка с B — с 0 на 1; R остаётся на месте

Каждая входная строка в таком обмене имеет одно целевое место, определённое ключом. Часть строк может уже находиться на нужном сегменте. Если обе стороны размещены неподходящим образом, план способен перераспределить обе. Конкретную форму выбирает оптимизатор по оценкам размеров и стоимости.

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

Broadcast: отправить маленькую сторону каждому

Broadcast Motion доставляет полный входной поток каждому участвующему сегменту. На рисунке R содержит две строки, A и B. Каждый сегмент получает обе и соединяет их со своей частью L. Большой поток L остаётся там, где уже находится.

Полный набор R с A и B копируется каждому сегменту, большая L остаётся на месте

Такой выбор бывает выгоден, когда после фильтров одна сторона действительно мала. Копирование небольшого набора может стоить меньше, чем перераспределение большого. Но объём копий растёт с числом получателей. Если оценка ошиблась и «маленькая» сторона оказалась широкой и большой, Broadcast нагружает сеть и память каждого исполнителя.

Broadcast и replicated-таблица дают локальную доступность данных разными способами. Replicated хранит постоянные копии таблицы. Broadcast передаёт результат выбранной ветви плана во время выполнения; им может стать уже отфильтрованная часть обычной распределённой таблицы.

Gather и объём обмена

Gather Motion собирает потоки в одном месте, например для выдачи ответа клиенту. Сбор трёх частичных сумм дёшев, сбор миллионов широких строк намного дороже. Наличие Gather в плане само по себе не указывает на проблему: нужно посмотреть, что именно проходит через него.

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

Сокращать поток нужно с сохранением смысла запроса. Агрегация до JOIN допустима, только если не меняет требуемую детализацию и число совпадений. Особенно внимательно проверяют outer JOIN, NULL и отношения «многие ко многим». Меньше строк в плане полезно лишь при верном результате.

Как читать Motion в плане

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

Не ставь целью убрать все Motion. Иногда одна пересылка даёт разумную стоимость запроса при удобной схеме хранения. Повод для расследования — большой неожиданный поток, неверная оценка, перекос после обмена или повторная передача того же объёма. В уроке EXPLAIN свяжем это с фактическими строками и памятью исполнителей.

Войти, чтобы отмечатьдальше →
11.5 →Партиции и отсечение данных