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:
DISTINCT sem especificar colunas:
DISTINCT com as colunas especificadas:
DISTINCT e ORDER BY
O ClickHouse permite usar as cláusulasDISTINCT e ORDER BY para colunas diferentes em uma mesma consulta. A cláusula DISTINCT é executada antes da cláusula ORDER BY.
Considere a tabela:
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áusulaSELECT, sem usar nenhuma função de agregação. No entanto, há algumas diferenças em relação à abordagem com GROUP BY:
DISTINCTpode ser aplicado junto comGROUP 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 intervaloLIMIT ... AFTER ... UNTILsemALLtambé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
ODISTINCT 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_distinctdefine um limiar, em bytes, da memória total da consulta. O padrão é0(desabilitado).max_bytes_ratio_before_external_distinctdefine 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.5e não tem efeito quando nenhum dos limites se aplica.
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:
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.