join_algorithm
Especifica qual algoritmo de 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 spill para algoritmos baseados em hash é configurado separadamente dejoin_algorithm. Todos os algoritmos baseados em hash usam max_bytes_before_external_join e max_bytes_ratio_before_external_join como limiares de spill.
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,
StringeNullable(String)). Isso pode alterar os tipos de resultado das colunasUSINGe pode fazer com que uma junção com uma tabela do mecanismoJoinfalhe comTYPE_MISMATCH. Acionado porfull_sorting_mergeeparallel_full_sorting_merge. ORDER BY ... LIMITno 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 porfull_sorting_merge,parallel_full_sorting_merge,partial_merge,prefer_partial_merge,grace_hasheauto, e também por um valor diferente de zero emmax_bytes_before_external_join/max_bytes_ratio_before_external_join.
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 explicitamente é indicado principalmente para fins de diagnóstico. Para habilitar o spill da junção, defina max_bytes_before_external_join ou max_bytes_ratio_before_external_join.
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 / 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 limiar 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
OR na seção JOIN ON.
Ao usar o algoritmo hash, a parte direita do JOIN é carregada na RAM.
- parallel_hash
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
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
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, EmbeddedRocksDB e 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
auto, hash join é tentado primeiro, e o algoritmo é alterado dinamicamente para outro algoritmo se o limite de memória for excedido.
- full_sorting_merge
- ie_join
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. Quando listado após outros algoritmos, como no valor padrão, ie_join é usado somente se a seção ON não tiver condições de igualdade. Quando listado primeiro, ele é usado sempre que a seção ON tiver duas condições de desigualdade, e as demais condições são aplicadas como filtro sobre o resultado da junção. Quando há mais de duas condições de desigualdade, as duas usadas pelo algoritmo são escolhidas pela seletividade estimada a partir das estatísticas de coluna; sem estatísticas, são usadas as duas primeiras na ordem sintática. Sem ie_join na lista, um INNER JOIN apenas com condições de desigualdade é executado como um CROSS JOIN com um filtro, e os demais tipos de junção, como um block nested loop join.
Ambas as entradas são acumuladas em memória antes da junção: max_rows_in_join e 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; 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
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
ASOFe 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_rowsã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.
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
partial_merge, se possível; caso contrário, usa hash. Obsoleto, igual a partial_merge,hash.
- default (obsoleto)
direct,hash, ou seja, tente usar a junção direta e o hash join (nessa ordem).
join_any_take_last_row
Altera o comportamento das operações de junção com strictnessANY quando a tabela da direita tem mais de uma linha correspondente para uma chave.
Essa configuração se aplica a tabelas com o motor
Join e a algoritmos de junção baseados em hash. Ela não tem efeito em uma junção block nested loop: sem uma chave de junção, não existe um grupo de linhas correspondentes do qual se possa tomar a última.Se uma junção for executada 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.- 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.
join_default_strictness
Define a strictness padrão das cláusulas JOIN. Valores possíveis:ALL— Se a tabela da direita tiver várias linhas correspondentes, o ClickHouse cria um produto cartesiano com as linhas correspondentes. Esse é o comportamento normal deJOINno 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 deANYeALLserão os mesmos.ASOF— Para junção de sequências com correspondência incerta.Empty string— SeALLouANYnão for especificado na consulta, o ClickHouse lança uma exceção.
join_on_disk_max_files_to_merge
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.
join_output_by_rowlist_perkey_rows_threshold
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.join_overflow_mode
Define qual ação o ClickHouse executa quando uma junção atinge qualquer um dos seguintes limites: Todo valor dejoin_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.
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.
THROW.
Veja também