> ## 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.

# configurações de sessão join_*

> Configurações de sessão do ClickHouse no grupo gerado de join_*.

export const VersionHistory = ({rows = []}) => {
  if (rows.length === 0) {
    return null;
  }
  const headers = ["Versão", "Valor padrão", "Comentário"];
  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
  }}>
        Histórico de versões
      </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
  }}>Tipo</div>
      <div style={{
    overflowWrap: "anywhere"
  }}>{type}</div>
      <div style={{
    fontWeight: 600,
    opacity: 0.72,
    marginInlineStart: "0.5rem"
  }}>Padrão</div>
      <div style={{
    overflowWrap: "anywhere"
  }}>{default_value}</div>
      {changeable_without_restart && <div style={{
    fontWeight: 600,
    opacity: 0.72,
    marginInlineStart: "0.5rem"
  }}>
          Pode ser alterado sem reiniciar
        </div>}
      {changeable_without_restart && <div style={{
    overflowWrap: "anywhere"
  }}>
          {changeable_without_restart}
        </div>}
    </div>;
};

Essas configurações estão disponíveis em [system.settings](/pt-BR/reference/system-tables/settings) e são geradas automaticamente com base no [código-fonte](https://github.com/ClickHouse/ClickHouse/blob/master/src/Core/Settings.cpp).

<h2 id="join_algorithm">
  join\_algorithm
</h2>

<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": "Adicionado `ie_join` à lista padrão; assim, uma junção cuja seção `ON` tenha apenas condições de desigualdade é executada com IEJoin em vez de um `CROSS JOIN` com filtro. Por estar por último, ele é usado apenas quando os outros algoritmos não se aplicam."}]}, {"id": "row-2","items": [{"label": "24.12"},{"label": "direct,parallel_hash,hash"},{"label": "'default' foi descontinuado em favor de algoritmos de junção especificados explicitamente; além disso, agora parallel_hash é preferido em vez de hash"}]}]} />

Especifica qual algoritmo de [JOIN](/pt-BR/reference/statements/select/join) é usado.

Vários algoritmos podem ser especificados, e um deles será escolhido para uma consulta específica com base em kind/strictness e no motor de tabela.

O fato de um algoritmo baseado em hash fazer spill para disco não faz parte dessa escolha: [`max_bytes_before_external_join`](/pt-BR/reference/settings/session-settings/max-bytes#max_bytes_before_external_join) / [`max_bytes_ratio_before_external_join`](/pt-BR/reference/settings/session-settings/max-bytes#max_bytes_ratio_before_external_join) são o limiar de spill para todos eles (e, uma vez que um dos dois seja diferente de zero, `enable_adaptive_memory_spill_scheduler` pode fazer o spill da junção ainda mais cedo, sob memory pressure), e [`max_rows_in_join`](/pt-BR/reference/settings/session-settings/max-rows#max_rows_in_join) / [`max_bytes_in_join`](/pt-BR/reference/settings/session-settings/max-bytes#max_bytes_in_join) são um limite rígido para todos eles, a menos que `legacy_join_size_limits_trigger_spilling` transforme esses dois limites novamente em acionadores de spill em disco. O valor escolhido determina como a junção faz spill: `grace_hash` particiona a tabela da direita a partir do primeiro bloco, enquanto `hash` e `parallel_hash` a coletam em memória e mudam de estratégia quando o limiar é ultrapassado.

A maioria dos algoritmos afeta uma consulta apenas quando é selecionada para ela. Alguns, no entanto, alteram o planejamento apenas por estarem listados — mesmo como uma alternativa de menor prioridade que não é selecionada ao final — porque a decisão é tomada antes da escolha do algoritmo. Há dois efeitos desse tipo:

* A inferência de tipo da chave de junção se torna mais restritiva (uma junção merge não pode unir chaves de tipos diferentes, por exemplo, `String` e `Nullable(String)`). Isso pode alterar os tipos de resultado das colunas `USING` e pode fazer com que uma junção com uma tabela do mecanismo `Join` falhe com `TYPE_MISMATCH`. Acionado por `full_sorting_merge` e `parallel_full_sorting_merge`.
* `ORDER BY ... LIMIT` no lado preservado de uma junção recebe uma ordenação explícita em vez de uma leitura na ordem da chave primária, pois presume-se que a junção interrompa a leitura ordenada (uma junção merge insere sua própria ordenação antes da junção; uma partial junção merge reordena os blocos da esquerda; uma junção que pode produzir blocos atrasados também não propaga a leitura ordenada). O resultado é o mesmo, mas o plano é menos eficiente. Acionado por `full_sorting_merge`, `parallel_full_sorting_merge`, `partial_merge`, `prefer_partial_merge`, `grace_hash` e `auto`, e também por um valor diferente de zero em `max_bytes_before_external_join` / `max_bytes_ratio_before_external_join`.

Ambos se aplicam mesmo quando a consulta acaba sendo executada com `hash` ou outro algoritmo. Se isso for indesejável, não liste os algoritmos acima em `join_algorithm` para as consultas afetadas.

Valores possíveis:

* grace\_hash

[Grace hash join](https://en.wikipedia.org/wiki/Hash_join#Grace_hash_join) é usado. O Grace hash oferece uma opção de algoritmo que permite executar junções complexas com bom desempenho, limitando o uso de memória.

`grace_hash` é externo desde o primeiro bloco: a tabela da direita é particionada imediatamente, enquanto `hash` e `parallel_hash` a coletam primeiro em memória e só a particionam quando o limiar de spill é ultrapassado. Escolha-o quando você já sabe que o lado direito não caberá na memória e quer pular a fase em memória. O próprio limiar de spill é o mesmo usado por todos os algoritmos hash, [`max_bytes_before_external_join`](/pt-BR/reference/settings/session-settings/max-bytes#max_bytes_before_external_join) / [`max_bytes_ratio_before_external_join`](/pt-BR/reference/settings/session-settings/max-bytes#max_bytes_ratio_before_external_join), e um dos dois precisa ser diferente de zero, a menos que `legacy_join_size_limits_trigger_spilling` esteja ativado. Sem um limiar, `grace_hash` é ignorado em favor do próximo algoritmo da lista, e rejeitado se for o único.

A primeira fase de um grace join lê a tabela da direita e a divide em N buckets dependendo do valor de hash das colunas de chave (inicialmente, N é `grace_hash_join_initial_buckets`). Isso é feito de modo a garantir que cada bucket possa ser processado de forma independente. As linhas do primeiro bucket são adicionadas a uma tabela hash em memória, enquanto as demais são salvas em disco. Se a tabela hash crescer além do limite de spill, o número de buckets é aumentado junto com o bucket atribuído a cada linha. Quaisquer linhas que não pertençam ao bucket atual são descarregadas e reatribuídas.

Oferece suporte a `INNER/LEFT/RIGHT/FULL ALL/ANY JOIN`.

* hash

É usado o [algoritmo hash join](https://en.wikipedia.org/wiki/Hash_join). A implementação mais genérica, que oferece suporte a todas as combinações de tipo e strictness e a múltiplas chaves de junção combinadas com `OR` na seção `JOIN ON`.

Ao usar o algoritmo `hash`, a parte direita do `JOIN` é carregada na RAM.

* parallel\_hash

Uma variação do `hash` join que divide os dados em buckets e constrói várias tabelas hash em vez de uma, de forma concorrente, para acelerar esse processo.

Ao usar o algoritmo `parallel_hash`, a parte direita do `JOIN` é carregada na RAM.

* partial\_merge

Uma variação do [algoritmo sort-merge](https://en.wikipedia.org/wiki/Sort-merge_join), em que apenas a tabela da direita é totalmente ordenada.

`RIGHT JOIN` e `FULL JOIN` são suportados apenas com strictness `ALL` (`SEMI`, `ANTI`, `ANY` e `ASOF` não são suportados).

Ao usar o algoritmo `partial_merge`, o ClickHouse ordena os dados e os grava no disco. O algoritmo `partial_merge` no ClickHouse difere ligeiramente da implementação clássica. Primeiro, o ClickHouse ordena a tabela da direita pelas chaves de junção em blocos e cria um índice min-max para os blocos ordenados. Em seguida, ele ordena partes da tabela da esquerda pela `chave de junção` e faz a junção delas com a tabela da direita. O índice min-max também é usado para ignorar blocos desnecessários da tabela da direita.

* direct

O algoritmo `direct` (também conhecido como nested loop) realiza um lookup na tabela da direita usando as linhas da tabela da esquerda como chaves.
É compatível com armazenamentos especiais, como tabelas [Dicionário](/pt-BR/reference/engines/table-engines/special/dictionary), [EmbeddedRocksDB](/pt-BR/reference/engines/table-engines/integrations/embedded-rocksdb) e [MergeTree](/pt-BR/reference/engines/table-engines/mergetree-family/mergetree).

Para tabelas MergeTree, o algoritmo envia filtros de chave de junção diretamente para a camada de armazenamento. Isso pode ser mais eficiente quando a chave pode usar o índice de chave primária da tabela para lookups; caso contrário, ele executa varreduras completas na tabela da direita para cada bloco da tabela da esquerda.

Oferece suporte a junções `INNER` e `LEFT` e apenas a chaves de junção de igualdade de uma única coluna, sem outras condições.

* auto

Quando definido como `auto`, `hash` join é tentado primeiro, e o algoritmo é alterado dinamicamente para outro algoritmo se o limite de memória for excedido.

* full\_sorting\_merge

[Algoritmo sort-merge](https://en.wikipedia.org/wiki/Sort-merge_join) com ordenação completa das tabelas unidas antes da junção.

* ie\_join

O algoritmo [IEJoin](https://vldb.org/pvldb/vol8/p2074-khayyat.pdf) baseado em ordenação para um `JOIN` cuja seção `ON` tem duas comparações de desigualdade (`<`, `<=`, `>`, `>=`) entre expressões das tabelas unidas. Oferece suporte a `ALL INNER/LEFT/RIGHT/FULL JOIN` e `SEMI`/`ANTI` `LEFT/RIGHT JOIN`.

A posição na lista define a prioridade: listado após outros algoritmos, como no valor padrão, IEJoin é usado somente quando eles não se aplicam (a seção `ON` não tem condições de igualdade); listado primeiro, ele é usado sempre que a seção `ON` tiver duas condições de desigualdade. As condições restantes (incluindo igualdades) são aplicadas como filtro sobre o resultado da junção para `ALL INNER JOIN` e avaliadas dentro do operador como uma condição residual que afeta a correspondência para os outros tipos. Quando a seção `ON` tem mais de duas condições de desigualdade elegíveis, as duas usadas pelo algoritmo são escolhidas pela seletividade estimada a partir das estatísticas de min/max das colunas (veja o tipo `basic` em [Estatísticas de coluna](/pt-BR/reference/engines/table-engines/mergetree-family/mergetree#column-statistics)); quando as estimativas não estão disponíveis (sem estatísticas, ou [`use_statistics`](/pt-BR/reference/settings/session-settings/use-statistics#use_statistics) está desativado), as duas primeiras na ordem sintática são usadas. Sem `ie_join` na lista, um `INNER JOIN` apenas com condições de desigualdade é executado como um `CROSS JOIN` com um filtro, e os outros tipos não têm suporte.

Ambas as entradas são acumuladas em memória antes da junção: [`max_rows_in_join`](/pt-BR/reference/settings/session-settings/max-rows#max_rows_in_join) e [`max_bytes_in_join`](/pt-BR/reference/settings/session-settings/max-bytes#max_bytes_in_join) limitam a entrada acumulada de ambos os lados em conjunto (não apenas o lado direito), com a ação em caso de overflow definida por [`join_overflow_mode`](/pt-BR/reference/settings/session-settings/join#join_overflow_mode); os índices de ordenação que o operator constrói sobre a entrada acumulada não são contabilizados no limite. O operator de junção em si é executado em uma única thread; apenas as ordenações pré-junção das entradas são paralelizadas.

* parallel\_full\_sorting\_merge

Igual a `full_sorting_merge`, mas junções por igualdade compatíveis com hash são divididas em shards pelo hash das chaves de junção em junções merge independentes por shard que são executadas em paralelo (até `max_threads`), em vez de uma única junção merge. Isso mantém o baixo uso de memória em streaming de uma junção merge enquanto utiliza todas as threads, e o resultado não é ordenado.

O sharding por hash das chaves de junção é aplicado apenas a junções por igualdade simples em tipos de chave cujo hash concorda com a comparação da junção merge, e somente quando nenhum dos lados já está ordenado. Ele é ignorado nestes casos:

* Junções `ASOF` e tipos de chave de ponto flutuante / `JSON` / `Object` / `Dynamic`: seus hashes não são consistentes com a comparação da junção merge, portanto chaves iguais poderiam acabar em shards diferentes.
* Lados que já estão ordenados (uma leitura MergeTree em ordem ou qualquer entrada pré-ordenada): uma dispersão que preserva a ordem nas junções merge por shard pode causar deadlock no pipeline. A leitura em ordem e sua otimização `read_in_order_use_virtual_row` são mantidas.
* Enquanto o iniciador cria um plano distribuído (`make_distributed_plan`), porque a ordenação dispersa não é serializável para execução remota. O plano local de fragmento único e os fragmentos por worker são reotimizados com essa configuração desativada, portanto ainda podem ser divididos em shards.

Ignorá-lo desabilita apenas essa reescrita, não o paralelismo em geral: a junção é executada como uma única `full_sorting_merge`, e os lados MergeTree lidos em ordem ainda podem ser divididos em shards na origem por intervalos de chave primária (que ordenam pela mesma comparação usada pela junção, para que chaves iguais permaneçam juntas) quando `query_plan_join_shard_by_pk_ranges` está habilitado.

* prefer\_partial\_merge

O ClickHouse sempre tenta usar a junção `partial_merge`, se possível; caso contrário, usa `hash`. *Obsoleto*, igual a `partial_merge,hash`.

* default (obsoleto)

Valor legado, não use mais.
Igual a `direct,hash`, ou seja, tente usar a junção direta e o hash join (nessa ordem).

<h2 id="join_any_take_last_row">
  join\_any\_take\_last\_row
</h2>

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

Altera o comportamento das operações JOIN com strictness `ANY` quando a tabela da direita tem mais de uma linha correspondente para uma chave.

<Note>
  Essa configuração se aplica a tabelas com o motor [`Join`](/pt-BR/reference/engines/table-engines/special/join) e a algoritmos de join baseados em hash.

  Se um join for executado em paralelo, a ordem das linhas pode ser não determinística. Isso significa que `join_any_take_last_row = 1` pode retornar uma linha não determinística em consultas `ANY JOIN`.
</Note>

Valores possíveis:

* 0 — Se a tabela da direita tiver mais de uma linha correspondente, apenas a primeira encontrada será combinada.
* 1 — Se a tabela da direita tiver mais de uma linha correspondente, apenas a última encontrada será combinada.

Veja também:

* [cláusula JOIN](/pt-BR/reference/statements/select/join)
* [motor de tabela Join](/pt-BR/reference/engines/table-engines/special/join)
* [join\_default\_strictness](/pt-BR/reference/settings/session-settings/join#join_default_strictness)

<h2 id="join_default_strictness">
  join\_default\_strictness
</h2>

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

Define a strictness padrão das [cláusulas JOIN](/pt-BR/reference/statements/select/join).

Valores possíveis:

* `ALL` — Se a tabela da direita tiver várias linhas correspondentes, o ClickHouse cria um [produto cartesiano](https://en.wikipedia.org/wiki/Cartesian_product) com as linhas correspondentes. Esse é o comportamento normal de `JOIN` no SQL padrão.
* `ANY` — Se a tabela da direita tiver várias linhas correspondentes, somente a primeira encontrada é combinada. Se a tabela da direita tiver apenas uma linha correspondente, os resultados de `ANY` e `ALL` serão os mesmos.
* `ASOF` — Para junção de sequências com correspondência incerta.
* `Empty string` — Se `ALL` ou `ANY` não for especificado na consulta, o ClickHouse lança uma exceção.

<h2 id="join_on_disk_max_files_to_merge">
  join\_on\_disk\_max\_files\_to\_merge
</h2>

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

Limita o número de arquivos permitidos para a ordenação paralela em operações MergeJoin quando são executadas em disco.

Quanto maior o valor da configuração, mais RAM é usada e menos E/S de disco é necessária.

Valores possíveis:

* Qualquer número inteiro positivo, a partir de 2.

<h2 id="join_output_by_rowlist_perkey_rows_threshold">
  join\_output\_by\_rowlist\_perkey\_rows\_threshold
</h2>

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

<VersionHistory rows={[{"id": "row-1","items": [{"label": "24.9"},{"label": "5"},{"label": "O limite inferior da média de linhas por chave na tabela à direita para determinar se a saída deve ser feita por lista de linhas em hash join."}]}]} />

O limite inferior da média de linhas por chave na tabela à direita para determinar se a saída deve ser feita por lista de linhas em hash join.

<h2 id="join_overflow_mode">
  join\_overflow\_mode
</h2>

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

Define qual ação o ClickHouse executa quando uma junção atinge qualquer um dos seguintes limites:

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

Todo valor de [`join_algorithm`](/pt-BR/reference/settings/session-settings/join#join_algorithm)
baseado em hash considera essa configuração, incluindo aqueles que fazem spill para disco: atingir o
limite interrompe a consulta em vez de acionar um spill. A exceção é
`legacy_join_size_limits_trigger_spilling`: com ela ativada, a parte de uma junção que
já é executada em disco continua fazendo spill em vez de aplicar essa configuração.
`ie_join` também a considera, sobre a entrada que acumula de ambos os lados. `partial_merge` ainda
lida com os limites mudando de estratégia — veja
[`join_algorithm`](/pt-BR/reference/settings/session-settings/join#join_algorithm).

Valores possíveis:

* `THROW` — o ClickHouse lança uma exceção e interrompe a consulta.
* `BREAK` — o ClickHouse interrompe a consulta e não lança uma exceção.

Valor padrão: `THROW`.

**Veja também**

* [cláusula junção](/pt-BR/reference/statements/select/join)
* [motor de tabela junção](/pt-BR/reference/engines/table-engines/special/join)

<h2 id="join_use_nulls">
  join\_use\_nulls
</h2>

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

Define o comportamento de [JOIN](/pt-BR/reference/statements/select/join). Ao combinar tabelas, células vazias podem aparecer. O ClickHouse as preenche de forma diferente com base nessa configuração.

Valores possíveis:

* 0 — As células vazias são preenchidas com o valor padrão do tipo de campo correspondente.
* 1 — `JOIN` se comporta da mesma forma que no SQL padrão. O tipo do campo correspondente é convertido para [Nullable](/pt-BR/reference/data-types/nullable), e as células vazias são preenchidas com [NULL](/pt-BR/reference/syntax).
