> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# join_* セッション設定

> join_* 生成グループに含まれる ClickHouse のセッション設定です。

export const VersionHistory = ({rows = []}) => {
  if (rows.length === 0) {
    return null;
  }
  const headers = ["バージョン", "デフォルト値", "コメント"];
  const border = "1px solid rgba(128, 128, 128, 0.3)";
  const cell = {
    border,
    padding: "0.25rem 0.5rem",
    textAlign: "start",
    verticalAlign: "top"
  };
  return <details className="not-prose" style={{
    border,
    borderRadius: "0.5rem",
    margin: "0.5rem 0",
    padding: "0.5rem 0.75rem",
    fontSize: "0.8125rem",
    lineHeight: "1.125rem"
  }}>
      <summary style={{
    cursor: "pointer",
    fontWeight: 600,
    opacity: 0.72
  }}>
        バージョン履歴
      </summary>
      <table style={{
    borderCollapse: "collapse",
    width: "100%",
    margin: "0.5rem 0 0"
  }}>
        <thead>
          <tr>
            {headers.map(header => <th key={header} style={{
    ...cell,
    fontWeight: 600,
    opacity: 0.72
  }}>
                {header}
              </th>)}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, row_index) => <tr key={row.id ?? row_index}>
              {(row.items ?? []).map((item, item_index) => <td key={item_index} style={{
    ...cell,
    overflowWrap: "anywhere"
  }}>
                  {item?.label}
                </td>)}
            </tr>)}
        </tbody>
      </table>
    </details>;
};

export const SettingsInfoBlock = ({type, default_value, changeable_without_restart}) => {
  return <div className="not-prose" style={{
    display: "flex",
    flexWrap: "wrap",
    alignItems: "baseline",
    columnGap: "0.5rem",
    rowGap: "0.125rem",
    margin: "0.375rem 0",
    fontSize: "0.8125rem",
    lineHeight: "1.125rem"
  }}>
      <div style={{
    fontWeight: 600,
    opacity: 0.72
  }}>型</div>
      <div style={{
    overflowWrap: "anywhere"
  }}>{type}</div>
      <div style={{
    fontWeight: 600,
    opacity: 0.72,
    marginInlineStart: "0.5rem"
  }}>デフォルト値</div>
      <div style={{
    overflowWrap: "anywhere"
  }}>{default_value}</div>
      {changeable_without_restart && <div style={{
    fontWeight: 600,
    opacity: 0.72,
    marginInlineStart: "0.5rem"
  }}>
          再起動せずに変更可能
        </div>}
      {changeable_without_restart && <div style={{
    overflowWrap: "anywhere"
  }}>
          {changeable_without_restart}
        </div>}
    </div>;
};

これらの設定は [system.settings](/ja/reference/system-tables/settings) で参照でき、[ソースコード](https://github.com/ClickHouse/ClickHouse/blob/master/src/Core/Settings.cpp) から自動生成されています。

## join\_algorithm

<SettingsInfoBlock type="JoinAlgorithm" default_value="direct,parallel_hash,hash,ie_join" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "26.8"},{"label": "direct,parallel_hash,hash,ie_join"},{"label": "`ie_join` がデフォルトリストに追加されました。これにより、`ON` 句に不等条件のみを含む join は、フィルタを伴う `CROSS JOIN` ではなく IEJoin で実行されます。最後に指定されているため、他のアルゴリズムが適用されない場合にのみ使用されます。"}]}, {"id": "row-2","items": [{"label": "24.12"},{"label": "direct,parallel_hash,hash"},{"label": "'default' は、join アルゴリズムを明示的に指定する方式が導入されたため非推奨になりました。また、現在は hash より parallel_hash が優先されます"}]}]} />

使用する [JOIN](/ja/reference/statements/select/join) アルゴリズムを指定します。

複数のアルゴリズムを指定できます。特定のクエリでは、kind/strictness とテーブルエンジンに基づいて、利用可能なアルゴリズムが選択されます。

ハッシュベースのアルゴリズムがディスクにスピルするかどうかは、この選択には含まれません。[`max_bytes_before_external_join`](/ja/reference/settings/session-settings/max-bytes#max_bytes_before_external_join) / [`max_bytes_ratio_before_external_join`](/ja/reference/settings/session-settings/max-bytes#max_bytes_ratio_before_external_join) はこれらすべてに共通のスピル threshold であり (この 2 つのいずれかがゼロ以外になると、メモリ逼迫時に `enable_adaptive_memory_spill_scheduler` によってさらに早く join をスピルさせることもできます) 、[`max_rows_in_join`](/ja/reference/settings/session-settings/max-rows#max_rows_in_join) / [`max_bytes_in_join`](/ja/reference/settings/session-settings/max-bytes#max_bytes_in_join) はすべてに共通のハードな上限です。ただし `legacy_join_size_limits_trigger_spilling` によって、この 2 つの上限を再びディスクへのスピルの trigger に戻すことができます。選択した値によって、join のスピルの仕方が決まります。`grace_hash` は最初の block から右テーブルをパーティション分割し、`hash` と `parallel_hash` はメモリ上に収集し、threshold を超えた時点で切り替えます。

ほとんどのアルゴリズムは、クエリに対して選択された場合にのみ影響します。ただし、一部は、最終的に選択されない低優先度のフォールバックとして列挙されているだけでも、アルゴリズムの選択前に決定が行われるため、プランニングを変更します。このような影響は 2 つあります。

* 結合キーの型推論がより厳格になります (たとえば、merge join では `String` と `Nullable(String)` のように異なる型のキーを結合できません)。これにより `USING` カラムの結果型が変わる可能性があり、`Join` エンジンテーブルへの join が `TYPE_MISMATCH` で失敗することがあります。`full_sorting_merge` と `parallel_full_sorting_merge` によりトリガーされます。
* join の保持側にある `ORDER BY ... LIMIT` は、join によって順序付き読み取りが崩れるとみなされるため、primary-key 順の読み取りではなく明示的なソートを行います (merge join は join 前の独自のソートを挿入し、partial merge join は左 blocks を再ソートします。また、遅延 blocks を生成できる 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](https://en.wikipedia.org/wiki/Hash_join) を使用します。Grace hash は、メモリ使用量を抑えつつ、複雑な結合を高い性能で実行できるアルゴリズムです。

`grace_hash` は最初の block から外部処理になります。右テーブルは直ちにパーティション分割されますが、`hash` と `parallel_hash` はまずメモリ上に収集し、スピル threshold を超えた時点で初めてパーティション分割します。右側がメモリに収まらないことが既に分かっており、インメモリのフェーズを省略したい場合に選択してください。スピル threshold 自体は、すべての hash アルゴリズムが使用するものと同じ [`max_bytes_before_external_join`](/ja/reference/settings/session-settings/max-bytes#max_bytes_before_external_join) / [`max_bytes_ratio_before_external_join`](/ja/reference/settings/session-settings/max-bytes#max_bytes_ratio_before_external_join) であり、`legacy_join_size_limits_trigger_spilling` が有効でない限り、この 2 つのいずれかがゼロ以外である必要があります。threshold がない場合、`grace_hash` はスキップされてリスト内の次のアルゴリズムが使用され、唯一のアルゴリズムである場合は拒否されます。

grace join の第 1 フェーズでは、右テーブルを読み取り、キーカラムの hash 値に応じて N 個の bucket に分割します (初期状態では、N は `grace_hash_join_initial_buckets` です)。これは、各 bucket を独立して処理できるように行われます。最初の bucket の行はメモリ内 hash table に追加され、その他はディスクに保存されます。hash table がスピル threshold を超えて増大すると、各行に割り当てられた bucket とともに bucket 数が増加します。現在の bucket に属さない行はすべてフラッシュされ、再割り当てされます。

`INNER/LEFT/RIGHT/FULL ALL/ANY JOIN` をサポートします。

* hash

[Hash join algorithm](https://en.wikipedia.org/wiki/Hash_join) が使用されます。kind と strictness のすべての組み合わせ、および `JOIN ON` 句で `OR` によって結合される複数の結合キーをサポートする、最も汎用的な実装です。

`hash` アルゴリズムを使用する場合、`JOIN` の右側は RAM に読み込まれます。

* parallel\_hash

`hash` join のバリエーションで、データを bucket に分割し、このプロセスを高速化するために 1 つではなく複数の hashtable を同時に構築します。

`parallel_hash` アルゴリズムを使用する場合、`JOIN` の右側は RAM に読み込まれます。

* partial\_merge

右テーブルのみを完全にソートする [sort-merge algorithm](https://en.wikipedia.org/wiki/Sort-merge_join) のバリエーションです。

`RIGHT JOIN` と `FULL JOIN` は、`ALL` strictness でのみサポートされます (`SEMI`、`ANTI`、`ANY`、`ASOF` はサポートされません)。

`partial_merge` アルゴリズムを使用する場合、ClickHouse はデータをソートしてディスクに書き出します。ClickHouse の `partial_merge` アルゴリズムは、従来の実装とは若干異なります。まず、ClickHouse は右テーブルを結合キーで block 単位にソートし、ソート済み block に対する min-max 索引を作成します。次に、左テーブルの part を `結合キー` でソートし、右テーブルに対して結合します。min-max 索引は、不要な右テーブル block をスキップするためにも使用されます。

* direct

`direct` (nested loop とも呼ばれます) アルゴリズムは、左テーブルの行をキーとして右テーブルをルックアップします。
[Dictionary](/ja/reference/engines/table-engines/special/dictionary)、[EmbeddedRocksDB](/ja/reference/engines/table-engines/integrations/embedded-rocksdb)、[MergeTree](/ja/reference/engines/table-engines/mergetree-family/mergetree) テーブルなどの特別なストレージでサポートされています。

MergeTree テーブルでは、このアルゴリズムは結合キーフィルタをストレージ層に直接プッシュダウンします。キーでテーブルの primary key index を使ってルックアップできる場合は、より効率的になることがあります。そうでない場合は、左テーブルの各 block ごとに右テーブル全体をフルスキャンします。

`INNER` と `LEFT` joins のみをサポートし、他の条件を含まない単一カラムの等価結合キーにのみ対応します。

* auto

`auto` に設定すると、まず ハッシュ結合 を試し、メモリ制限を超えた場合は実行中に別のアルゴリズムへ切り替えます。

* full\_sorting\_merge

結合前に結合対象テーブルを完全にソートする [Sort-merge algorithm](https://en.wikipedia.org/wiki/Sort-merge_join) です。

* ie\_join

結合対象テーブルの式間に 2 つの不等比較 (`<`、`<=`、`>`、`>=`) を含む `ON` 句を持つ `JOIN` 向けの、ソートベースの [IEJoin](https://vldb.org/pvldb/vol8/p2074-khayyat.pdf) アルゴリズムです。`ALL INNER/LEFT/RIGHT/FULL JOIN` および `SEMI`/`ANTI` `LEFT/RIGHT JOIN` をサポートします。

リスト内の位置で優先順位が決まります。デフォルト値のように他のアルゴリズムの後に記載した場合、IEJoin はそれらが適用されない場合にのみ使用されます (`ON` 句に等価条件がない場合)。先頭に記載した場合、`ON` 句に 2 つの不等条件があれば常に使用されます。残りの条件 (等価条件を含む) は、`ALL INNER JOIN` では結合結果に対するフィルタとして適用され、その他の kind ではマッチングに影響する残余条件として operator 内で評価されます。`ON` 句に適格な不等条件が 3 つ以上ある場合、アルゴリズムで使用する 2 つはカラムの min/max 統計から推定した選択性に基づいて選択されます ([Column statistics](/ja/reference/engines/table-engines/mergetree-family/mergetree#column-statistics) の `basic` 型を参照)。推定値を使用できない場合 (統計がない、または [`use_statistics`](/ja/reference/settings/session-settings/use-statistics#use_statistics) が無効になっている場合) は、構文上の順序で先頭の 2 つが使用されます。リストに `ie_join` がない場合、不等条件のみを持つ `INNER JOIN` はフィルタ付きの `CROSS JOIN` として実行され、その他の kind はサポートされません。

両方の入力は join 前にメモリに蓄積されます。[`max_rows_in_join`](/ja/reference/settings/session-settings/max-rows#max_rows_in_join) と [`max_bytes_in_join`](/ja/reference/settings/session-settings/max-bytes#max_bytes_in_join) は、両側の蓄積された入力の合計を制限します (右側だけではありません) 。オーバーフロー時の動作は [`join_overflow_mode`](/ja/reference/settings/session-settings/join#join_overflow_mode) で設定します。蓄積された入力に対して演算子が構築するソート索引は、この制限には含まれません。join 演算子自体は単一スレッドで実行されます。並列化されるのは、入力に対する join 前のソートのみです。

* parallel\_full\_sorting\_merge

`full_sorting_merge` と同じですが、hash 互換の等価 join は、単一の merge join ではなく、結合キーの hash によって独立した分片ごとの merge join に分割され、それらが並列に実行されます (`max_threads` まで) 。これにより、すべてのスレッドを使用しながら merge join の低いストリーミングメモリ使用量を維持できますが、結果は順序付けられません。

結合キーによる hash 分片化は、hash が merge join の比較と一致するキー型の単純な等価 join にのみ適用され、どちらの側もすでにソートされていない場合に限られます。次の場合はスキップされます。

* `ASOF` joins、および浮動小数点 / `JSON` / `Object` / `Dynamic` キー型: これらの hash は merge join の比較と一貫しないため、等しいキーが異なる分片に配置される可能性があります。
* すでにソートされている側 (順序どおりの MergeTree 読み取り、または事前にソートされた入力): 分片ごとの merge への順序保持 scatter により、パイプラインがデッドロックする可能性があります。代わりに、順序どおりの読み取りとその `read_in_order_use_virtual_row` 最適化が維持されます。
* initiator が distributed プラン (`make_distributed_plan`) を構築する場合: scatter されたソートはリモート実行用にシリアライズできないためです。ローカルの単一フラグメント プラン と worker ごとのフラグメントは、その設定を無効にして再最適化されるため、引き続き分片化できます。

これをスキップしても無効になるのはこの書き換えのみで、並列度全般が無効になるわけではありません。join は単一の `full_sorting_merge` として実行され、順序どおりに読み取る MergeTree 側は、`query_plan_join_shard_by_pk_ranges` が有効な場合、primary key の範囲によってソース側で分片化できます (これらは join が使用するのと同じ比較で順序付けられるため、等しいキーはまとまったままになります)。

* prefer\_partial\_merge

ClickHouse は可能な限り常に `partial_merge` join を使用しようとし、それができない場合は hash を使用します。*非推奨* で、`partial_merge,hash` と同じです。

* default (非推奨)

レガシーな値であり、今後は使用しないでください。
`direct,hash` と同じで、direct join と ハッシュ結合 を (この順序で) 使用しようとします。

## join\_any\_take\_last\_row

<SettingsInfoBlock type="Bool" default_value="0" />

右テーブルで、あるキーに一致する行が複数ある場合の、`ANY` strictness を持つ JOIN演算の動作を変更します。

<Note>
  この設定は、[`Join`](/ja/reference/engines/table-engines/special/join) エンジンのテーブルと、ハッシュベースの JOIN アルゴリズムに適用されます。

  JOIN が並列に構築される場合、行の順序は非決定論的になることがあります。つまり、`join_any_take_last_row = 1` を設定すると、`ANY JOIN` クエリで非決定論的な行が返される可能性があります。
</Note>

設定可能な値:

* 0 — 右テーブルに一致する行が複数ある場合、最初に見つかった 1 行だけが結合されます。
* 1 — 右テーブルに一致する行が複数ある場合、最後に見つかった 1 行だけが結合されます。

関連項目:

* [JOIN 句](/ja/reference/statements/select/join)
* [Join テーブルエンジン](/ja/reference/engines/table-engines/special/join)
* [join\_default\_strictness](/ja/reference/settings/session-settings/join#join_default_strictness)

## join\_default\_strictness

<SettingsInfoBlock type="JoinStrictness" default_value="ALL" />

[JOIN clauses](/ja/reference/statements/select/join) のデフォルトの strictness を設定します。

設定可能な値:

* `ALL` — 右テーブルに一致する行が複数ある場合、ClickHouse は一致した行の[デカルト積](https://en.wikipedia.org/wiki/Cartesian_product)を作成します。これは Standard SQL における通常の `JOIN` の動作です。
* `ANY` — 右テーブルに一致する行が複数ある場合、最初に見つかった 1 行だけを結合します。右テーブルに一致する行が 1 行しかない場合、`ANY` と `ALL` の結果は同じです。
* `ASOF` — あいまいな一致条件で数列を結合する場合に使用します。
* `Empty string` — クエリで `ALL` または `ANY` が指定されていない場合、ClickHouse では例外がスローされます。

## join\_on\_disk\_max\_files\_to\_merge

<SettingsInfoBlock type="UInt64" default_value="64" />

MergeJoin がディスク上で実行される場合に、並列ソートで使用できるファイル数を制限します。

この設定値を大きくするほど、使用するRAMは増え、必要なディスクI/Oは少なくなります。

設定可能な値:

* 2以上の任意の正の整数。

## join\_output\_by\_rowlist\_perkey\_rows\_threshold

<SettingsInfoBlock type="UInt64" default_value="5" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "24.9"},{"label": "5"},{"label": "ハッシュ結合で行リストで出力するかどうかを判断するための、右テーブルにおけるキーごとの平均行数の下限。"}]}]} />

ハッシュ結合で行リストで出力するかどうかを判断するための、右テーブルにおけるキーごとの平均行数の下限。

## join\_overflow\_mode

<SettingsInfoBlock type="OverflowMode" default_value="throw" />

join が次のいずれかの制限に達したときに、ClickHouse がどのような動作を行うかを定義します。

* [max\_bytes\_in\_join](/ja/reference/settings/session-settings/max-bytes#max_bytes_in_join)
* [max\_rows\_in\_join](/ja/reference/settings/session-settings/max-rows#max_rows_in_join)

ハッシュベースの [`join_algorithm`](/ja/reference/settings/session-settings/join#join_algorithm)
の値はすべて、ディスクへスピルするものも含めてこの設定に従います。つまり、制限に達すると
スピルがトリガーされるのではなくクエリが停止します。例外は
`legacy_join_size_limits_trigger_spilling` で、これを有効にすると、すでにディスク上で
実行されている join の部分は、この設定に従うのではなくさらにスピルします。
`ie_join` も、両側から蓄積した入力に対してこの設定に従います。`partial_merge` は依然として
戦略の切り替えによってこれらの制限を処理します。詳しくは
[`join_algorithm`](/ja/reference/settings/session-settings/join#join_algorithm) を参照してください。

設定可能な値:

* `THROW` — ClickHouse は例外をスローしてクエリを停止します。
* `BREAK` — ClickHouse はクエリを停止し、例外はスローしません。

デフォルト値: `THROW`。

**関連項目**

* [JOIN 句](/ja/reference/statements/select/join)
* [Join テーブルエンジン](/ja/reference/engines/table-engines/special/join)

## join\_use\_nulls

<SettingsInfoBlock type="Bool" default_value="0" />

[JOIN](/ja/reference/statements/select/join) の動作を設定します。テーブルを結合する際、空のセルが生じることがあります。ClickHouse はこの設定に応じて、それらを異なる方法で補完します。

設定可能な値:

* 0 — 空のセルは、対応するフィールド型のデフォルト値で補完されます。
* 1 — `JOIN` は Standard SQL と同じように動作します。対応するフィールドの型は [Nullable](/ja/reference/data-types/nullable) に変換され、空のセルは [NULL](/ja/reference/syntax) で補完されます。
