- Build phase. ClickHouse reads one input completely and stores it in a data structure that supports matching, such as a hash table or a set of sorted blocks. This input is the build side.
- Probe phase. ClickHouse streams the other input block by block and matches each row against the data structure from the build phase. This input is the probe side.
direct algorithm has no build phase, because the right-hand side already exists as a key-value structure. The full_sorting_merge algorithm sorts both inputs and merges them. The ie_join algorithm accumulates both inputs before it joins them.
Query planner behavior
The query planner can change the inputs of a JOIN before an algorithm runs. The following optimizations apply.Automatic build-side selection
Since version 24.12, the planner can swap the two inputs of a JOIN so that the smaller input becomes the build side. It compares the estimated row counts of both inputs and swaps them for a hash-based JOIN when the left input is estimated to be smaller. Thequery_plan_join_swap_table setting controls this behavior.
When the inputs are swapped, a LEFT JOIN is executed as a RIGHT JOIN, and the reverse. The swapped order is visible in EXPLAIN output.
Multi-table JOIN reordering
For a query that joins several tables in the same subquery, the planner can change the order in which the tables are joined. Thequery_plan_optimize_join_order_limit setting sets the maximum number of tables that the planner reorders. The default value is 10. The value 1 disables reordering.
Use of column statistics
Build-side selection and JOIN reordering depend on row-count estimates. Without column statistics, the planner derives estimates from the primary index, and these estimates can be imprecise. With column statistics, the planner uses statistics to estimate the selectivity of filters and the cardinality of JOIN keys. Theuse_statistics setting controls whether the optimizer uses statistics. The materialize_statistics_on_insert setting controls whether statistics are built for newly inserted data.
Filter pushdown
Whenquery_plan_filter_push_down is enabled, the planner moves WHERE conditions below the JOIN so that each input is filtered before the build and probe phases.
- A condition that references columns of only one input is applied to that input.
- For a
LEFTJOIN, conditions are not pushed to the right input. For aRIGHTJOIN, conditions are not pushed to the left input. - A condition on a JOIN key of one input can also be applied to the other input, because the key columns of both inputs are equal for every matched row.
- Conditions are not pushed into a right-hand side that is already filled, such as a dictionary, or into the right-hand side of an
ASOFJOIN.