join_algorithm
- Вывод типов ключей JOIN становится строже (например, соединение слиянием не может соединять ключи разных типов, такие как
StringиNullable(String)). Это может изменить типы результатов столбцовUSINGи привести к сбою JOIN с таблицей движкаJoinс ошибкойTYPE_MISMATCH. Срабатывает дляfull_sorting_mergeиparallel_full_sorting_merge. ORDER BY ... LIMITна сохраняемой стороне JOIN получает явную сортировку вместо чтения в порядке primary key, поскольку предполагается, что JOIN нарушает упорядоченное чтение (соединение слиянием вставляет собственную сортировку перед JOIN; частичное соединение слиянием повторно сортирует левые блоки; JOIN, который может создавать отложенные блоки, также не передаёт упорядоченное чтение). Результат тот же, но план менее эффективен. Срабатывает дляfull_sorting_merge,parallel_full_sorting_merge,partial_merge,prefer_partial_merge,grace_hashиauto, а также при ненулевом значенииmax_bytes_before_external_join/max_bytes_ratio_before_external_join.
hash или другим алгоритмом. Если это нежелательно, не указывайте перечисленные выше алгоритмы в join_algorithm для затронутых запросов.
Возможные значения:
- grace_hash
grace_hash_join_initial_buckets). Это делается так, чтобы каждый бакет можно было обрабатывать независимо. Строки из первого бакета добавляются во внутреннюю hash table, а остальные сохраняются на disk. Если hash table вырастает сверх memory limit (например, заданного через max_bytes_in_join), количество бакетов увеличивается, и для каждой строки заново определяется назначенный бакет. Все строки, которые не принадлежат текущему бакету, сбрасываются и перераспределяются.
Поддерживает INNER/LEFT/RIGHT/FULL ALL/ANY JOIN.
- hash
OR в секции JOIN ON.
При использовании алгоритма hash правая часть JOIN загружается в оперативную память.
- parallel_hash
hash JOIN, который разбивает данные на бакеты и параллельно строит несколько hash table вместо одной, чтобы ускорить этот процесс.
При использовании алгоритма parallel_hash правая часть JOIN загружается в оперативную память.
- partial_merge
RIGHT JOIN и FULL JOIN поддерживаются только со strictness ALL (SEMI, ANTI, ANY и ASOF не поддерживаются).
При использовании алгоритма partial_merge ClickHouse сортирует данные и выгружает их на disk. Алгоритм partial_merge в ClickHouse немного отличается от классической реализации. Сначала ClickHouse сортирует правую таблицу по join keys блоками и создаёт min-max index для отсортированных блоков. Затем он сортирует части левой таблицы по join key и выполняет их JOIN с правой таблицей. Min-max index также используется для пропуска ненужных блоков правой таблицы.
- direct
direct (также известный как nested loop) выполняет lookup в правой таблице, используя строки из левой таблицы в качестве ключей.
Он поддерживается специальными хранилищами, такими как Dictionary, EmbeddedRocksDB и таблицами MergeTree.
Для таблиц MergeTree алгоритм передаёт фильтры по join key напрямую на уровень хранения. Это может быть эффективнее, если ключ позволяет использовать primary key index таблицы для lookup; в противном случае для каждого блока левой таблицы выполняется полное сканирование правой таблицы.
Поддерживает INNER и LEFT joins и только одностолбцовые ключи JOIN по равенству без дополнительных условий.
- auto
auto, сначала пробуется hash JOIN, а затем алгоритм на лету переключается на другой, если превышается memory limit.
- full_sorting_merge
- ie_join
JOIN, в секции ON которого есть два сравнения на неравенство (<, <=, >, >=) между выражениями соединяемых таблиц. Поддерживает ALL INNER/LEFT/RIGHT/FULL JOIN и SEMI/ANTI LEFT/RIGHT JOIN.
Позиция в списке задаёт приоритет: если IEJoin указан после других алгоритмов, он используется только когда они неприменимы (в секции ON нет условий равенства); если указан первым, он используется всегда, когда секция ON содержит два условия неравенства. Остальные условия (включая равенства) применяются как фильтр к результату JOIN для ALL INNER JOIN, а для остальных видов вычисляются внутри оператора как остаточное условие, влияющее на сопоставление. Без ie_join в списке INNER JOIN, содержащий только условия неравенства, выполняется как CROSS JOIN с фильтром, а остальные виды не поддерживаются.
Оба входа накапливаются в памяти перед выполнением JOIN: max_rows_in_join и max_bytes_in_join ограничивают суммарный объём входных данных обеих сторон (не только правой), а действие при переполнении задаётся через join_overflow_mode; индексы сортировки, которые оператор строит поверх накопленных входных данных, не учитываются в ограничении. Сам оператор JOIN выполняется в одном потоке; распараллеливается только предварительная сортировка входных данных.
- parallel_full_sorting_merge
full_sorting_merge, но JOIN по равенству, совместимые с hash, сегментируются по hash ключей JOIN на независимые merge JOIN для каждого сегмента, которые выполняются параллельно (до max_threads), вместо одного merge JOIN. Это сохраняет низкое потоковое использование памяти merge JOIN при задействовании всех потоков, а результат не упорядочен.
Hash-сегментирование по ключам JOIN применяется только к простым JOIN по равенству для типов ключей, hash которых согласуется со сравнением merge JOIN, и только если ни одна из сторон уже не отсортирована. Оно пропускается в следующих случаях:
- JOIN
ASOFи типы ключей floating-point /JSON/Object/Dynamic: их hash несовместимы со сравнением merge JOIN, поэтому равные ключи могут попасть в разные сегменты. - Стороны, которые уже отсортированы (чтение MergeTree по порядку или любые предварительно отсортированные входные данные): сохраняющее порядок распределение по merge JOIN для каждого сегмента может привести к взаимной блокировке конвейера. Вместо этого сохраняются чтение по порядку и его оптимизация
read_in_order_use_virtual_row. - Когда инициатор строит распределённый план (
make_distributed_plan), поскольку распределённая сортировка не сериализуема для удалённого выполнения. Локальный односегментный план и фрагменты для каждого worker повторно оптимизируются с отключённой этой настройкой, поэтому всё ещё могут быть сегментированы.
full_sorting_merge, а стороны MergeTree с чтением по порядку всё ещё могут быть сегментированы в источнике по диапазонам primary key (которые упорядочиваются тем же сравнением, что использует JOIN, поэтому равные ключи остаются вместе), если включён query_plan_join_shard_by_pk_ranges.
- prefer_partial_merge
partial_merge, если это возможно; в противном случае используется hash. Устарело, то же самое, что partial_merge,hash.
- default (deprecated)
direct,hash, то есть сначала используется direct join, а затем hash join (в этом порядке).
join_any_take_last_row
ANY, когда в правой таблице для ключа есть более одной совпадающей строки.
Этот параметр применяется к таблицам с движком
Join и алгоритмам JOIN на основе хеша.Если JOIN строится параллельно, порядок строк может быть недетерминированным. Это означает, что join_any_take_last_row = 1 может возвращать недетерминированную строку для запросов ANY JOIN.- 0 — Если в правой таблице есть более одной совпадающей строки, присоединяется только первая найденная.
- 1 — Если в правой таблице есть более одной совпадающей строки, присоединяется только последняя найденная.
join_default_strictness
ALL— Если в правой таблице есть несколько совпадающих строк, ClickHouse создаёт декартово произведение из совпадающих строк. Это обычное поведениеJOINв стандартном SQL.ANY— Если в правой таблице есть несколько совпадающих строк, присоединяется только первая найденная. Если в правой таблице есть только одна совпадающая строка, результатыANYиALLбудут одинаковыми.ASOF— Для соединения последовательностей с неточным совпадением.Empty string— Если в запросе не указаныALLилиANY, ClickHouse генерирует исключение.
join_on_disk_max_files_to_merge
- Любое положительное целое число, начиная с 2.
join_output_by_rowlist_perkey_rows_threshold
join_overflow_mode
hash, parallel_hash и ie_join
параметра join_algorithm. Другие
алгоритмы (например, partial_merge, grace_hash, auto) обрабатывают
эти ограничения иначе — выгружают данные на диск, переразбивают их на партиции или переключают
стратегию — см.
join_algorithm.
Возможные значения:
THROW— ClickHouse генерирует исключение и останавливает запрос.BREAK— ClickHouse останавливает запрос и не генерирует исключение.
THROW.
См. также