join_algorithm
Specifies which JOIN algorithm is used. Several algorithms can be specified, and an available one would be chosen for a particular query based on kind/strictness and table engine. Most algorithms affect a query only when they are the one selected for it. Some, however, change planning merely by being listed — even as a lower-priority fallback that is not ultimately selected — because the decision is made before the algorithm is picked. There are two such effects:- Join-key type inference becomes stricter (a merge join cannot join keys of different types, for example
StringandNullable(String)). This can change the result types ofUSINGcolumns, and can make a join into aJoin-engine table fail withTYPE_MISMATCH. Triggered byfull_sorting_mergeandparallel_full_sorting_merge. ORDER BY ... LIMITon the preserved side of a join gets an explicit sort instead of a read in primary-key order, because the join is assumed to break the ordered read (a merge join inserts its own pre-join sort; a partial merge join re-sorts the left blocks; a join that can produce delayed blocks does not propagate the ordered read either). The result is the same, the plan is less efficient. Triggered byfull_sorting_merge,parallel_full_sorting_merge,partial_merge,prefer_partial_merge,grace_hashandauto, and also by a non-zeromax_bytes_before_external_join/max_bytes_ratio_before_external_join.
hash or another algorithm. If this is undesirable, do not list the algorithms above in join_algorithm for the affected queries.
Possible values:
- grace_hash
grace_hash_join_initial_buckets). This is done in a way to ensure that each bucket can be processed independently. Rows from the first bucket are added to an in-memory hash table while the others are saved to disk. If the hash table grows beyond the memory limit (e.g., as set by max_bytes_in_join, the number of buckets is increased and the assigned bucket for each row. Any rows which don’t belong to the current bucket are flushed and reassigned.
Supports INNER/LEFT/RIGHT/FULL ALL/ANY JOIN.
- hash
OR in the JOIN ON section.
When using the hash algorithm, the right part of JOIN is uploaded into RAM.
- parallel_hash
hash join that splits the data into buckets and builds several hashtables instead of one concurrently to speed up this process.
When using the parallel_hash algorithm, the right part of JOIN is uploaded into RAM.
- partial_merge
RIGHT JOIN and FULL JOIN are supported only with ALL strictness (SEMI, ANTI, ANY, and ASOF are not supported).
When using the partial_merge algorithm, ClickHouse sorts the data and dumps it to the disk. The partial_merge algorithm in ClickHouse differs slightly from the classic realization. First, ClickHouse sorts the right table by joining keys in blocks and creates a min-max index for sorted blocks. Then it sorts parts of the left table by the join key and joins them over the right table. The min-max index is also used to skip unneeded right table blocks.
- direct
direct (also known as nested loop) algorithm performs a lookup in the right table using rows from the left table as keys.
It’s supported by special storages such as Dictionary, EmbeddedRocksDB, and MergeTree tables.
For MergeTree tables, the algorithm pushes join key filters directly to the storage layer. This can be more efficient when the key can use the table’s primary key index for lookups, otherwise it performs full scans of the right table for each left table block.
Supports INNER and LEFT joins and only single-column equality join keys without other conditions.
- auto
auto, hash join is tried first, and the algorithm is switched on the fly to another algorithm if the memory limit is violated.
- full_sorting_merge
- parallel_full_sorting_merge
full_sorting_merge, but hash-compatible equality joins are sharded by the hash of the join keys into independent per-shard merge joins that run in parallel (up to max_threads), instead of a single merge join. This keeps the low, streaming memory usage of a merge join while using all threads, and the result is not ordered.
Hash-sharding by the join keys is applied only to plain equality joins on key types whose hash agrees with the merge-join comparison, and only when neither side is already sorted. It is skipped in these cases:
ASOFjoins, and floating-point /JSON/Object/Dynamickey types: their hashes are not consistent with the merge-join comparison, so equal keys could land in different shards.- Sides that are already sorted (a MergeTree read in order, or any pre-sorted input): an order-preserving scatter into the per-shard merges can deadlock the pipeline. The in-order read and its
read_in_order_use_virtual_rowoptimization are kept instead. - While the initiator builds a distributed plan (
make_distributed_plan), because the scattered sort is not serializable for remote execution. The local single-fragment plan and the per-worker fragments re-optimize with that setting disabled, so they can still be sharded.
full_sorting_merge, and MergeTree sides read in order can still be sharded at the source by primary-key ranges (which order by the same comparison the join uses, so equal keys stay together) when query_plan_join_shard_by_pk_ranges is enabled.
- prefer_partial_merge
partial_merge join if possible, otherwise, it uses hash. Deprecated, same as partial_merge,hash.
- default (deprecated)
direct,hash, i.e. try to use direct join and hash join (in this order).
join_any_take_last_row
Changes the behaviour of join operations withANY strictness when the right table has more than one matching row for a key.
This setting applies to
Join engine tables and hash-based join algorithms.If a join is built in parallel, the order of rows can be non-deterministic. This means that join_any_take_last_row = 1 can return a non-deterministic row for ANY JOIN queries.- 0 — If the right table has more than one matching row, only the first one found is joined.
- 1 — If the right table has more than one matching row, only the last one found is joined.
join_default_strictness
Sets default strictness for JOIN clauses. Possible values:ALL— If the right table has several matching rows, ClickHouse creates a Cartesian product from matching rows. This is the normalJOINbehaviour from standard SQL.ANY— If the right table has several matching rows, only the first one found is joined. If the right table has only one matching row, the results ofANYandALLare the same.ASOF— For joining sequences with an uncertain match.Empty string— IfALLorANYis not specified in the query, ClickHouse throws an exception.
join_on_disk_max_files_to_merge
Limits the number of files allowed for parallel sorting in MergeJoin operations when they are executed on disk. The bigger the value of the setting, the more RAM is used and the less disk I/O is needed. Possible values:- Any positive integer, starting from 2.
join_output_by_rowlist_perkey_rows_threshold
The lower limit of per-key average rows in the right table to determine whether to output by row list in hash join.join_overflow_mode
Defines what action ClickHouse performs when a join reaches any of the following limits: This setting is honored only by thehash and parallel_hash
join_algorithm values. Other
algorithms (for example, partial_merge, grace_hash, auto) handle the
limits differently — by spilling to disk, re-partitioning, or switching
strategy — see
join_algorithm.
Possible values:
THROW— ClickHouse throws an exception and stops the query.BREAK— ClickHouse stops the query and does not throw an exception.
THROW.
See Also