Skip to main content
Se SELECT DISTINCT for especificado, apenas linhas únicas permanecerão no resultado da consulta. Assim, de cada conjunto de linhas totalmente idênticas no resultado, apenas uma linha será mantida. Você pode especificar a lista de colunas que devem ter valores únicos: SELECT DISTINCT ON (column1, column2,...). Se as colunas não forem especificadas, todas serão levadas em consideração. Considere a tabela:
Usando DISTINCT sem especificar colunas:
Usando DISTINCT com as colunas especificadas:

DISTINCT e ORDER BY

O ClickHouse permite usar as cláusulas DISTINCT e ORDER BY para colunas diferentes em uma mesma consulta. A cláusula DISTINCT é executada antes da cláusula ORDER BY. Considere a tabela:
Seleção de dados:
Selecionando dados com uma direção de ordenação diferente:
A linha 2, 4 foi descartada antes da ordenação. Leve essa particularidade da implementação em conta ao escrever consultas.

Processamento de NULL

DISTINCT funciona com NULL como se NULL fosse um valor específico e NULL==NULL. Em outras palavras, nos resultados de DISTINCT, diferentes combinações com NULL aparecem apenas uma vez. Isso difere do processamento de NULL na maioria dos outros contextos.

Alternativas

É possível obter o mesmo resultado aplicando GROUP BY ao mesmo conjunto de valores especificado na cláusula SELECT, sem usar nenhuma função de agregação. No entanto, há algumas diferenças em relação à abordagem com GROUP BY:
  • DISTINCT pode ser aplicado junto com GROUP BY.
  • Antes de a execução externa começar, uma consulta sem ORDER BY pode parar assim que tiver lido linhas distintas suficientes para satisfazer o LIMIT.
  • Antes de a execução externa começar e quando ORDER BY é omitido, um intervalo LIMIT ... AFTER ... UNTIL sem ALL também pode parar a consulta assim que o intervalo termina.
  • Os blocos de dados são produzidos à medida que são processados até que a execução externa comece.

DISTINCT em memória externa

O DISTINCT pode gravar dados temporários em disco para processar conjuntos de valores únicos grandes demais para caberem na memória. Isso exige E/S de disco adicional e pode deixar as consultas mais lentas. Duas configurações controlam quando o spill começa:
  • max_bytes_before_external_distinct define um limiar, em bytes, da memória total da consulta. O padrão é 0 (desabilitado).
  • max_bytes_ratio_before_external_distinct define uma fração da memória disponível dentro dos limites do servidor ou do usuário, medida no início da execução. O padrão é 0.5 e não tem efeito quando nenhum dos limites se aplica.
Quando ambos os limiares se aplicam, o menor prevalece. Defina as duas configurações como 0 para desabilitar o spill. O max_memory_usage não afeta a razão. Para configurar o spill em relação a um limite de memória da consulta, defina um limiar absoluto abaixo desse limite. Por exemplo, esta consulta usa um limiar de spill de 16 MiB com um limite de memória de consulta de 256 MiB:
Esses limiares não limitam o consumo de memória. Deixe espaço para outras operações de processamento de consultas e para o próprio spill. O spill também pode começar mais cedo sob pressão de memória. As linhas podem ser retornadas antes do spill, e um LIMIT atendido nesse estágio pode encerrar a consulta antecipadamente. Assim que o spill começa, o restante da entrada precisa ser lido antes que os demais resultados possam ser retornados. Se a consulta incluir ORDER BY, esses resultados são retornados na ordem solicitada. Quando o DISTINCT usa uma entrada ordenada por um prefixo de suas chaves, não ocorre spill. Um grupo grande de linhas com o mesmo prefixo ainda pode consumir bastante memória. Assim como em optimize_distinct_in_order, o spill pode deduplicar valores de ponto flutuante que têm representações binárias diferentes, mas que são iguais na comparação, incluindo 0.0 e -0.0, ou valores NaN com cargas úteis diferentes.
Última modificação em 26 de setembro de 2026