Pular para o conteúdo principal
Este guia faz parte de uma coletânea de aprendizados obtidos em encontros da comunidade. Para ver mais soluções e insights práticos, você pode navegar por problema específico. Está com problemas com visões materializadas? Confira o guia de insights da comunidade sobre Visões materializadas. Se você está enfrentando consultas lentas e quer ver mais exemplos, também temos um guia de Otimização de consultas.

Ordene por cardinalidade (da menor para a maior)

O índice primário do ClickHouse funciona melhor quando colunas de baixa cardinalidade vêm primeiro, permitindo pular grandes fragmentos de dados com eficiência. Colunas de alta cardinalidade mais adiante na chave fornecem uma ordenação mais granular dentro desses fragmentos. Comece com colunas que têm poucos valores únicos (como status, categoria e país) e termine com colunas que têm muitos valores únicos (como user_id, timestamp e session_id). Confira mais documentação sobre cardinalidade e índices primários:

A granularidade do tempo importa

Ao usar timestamps na cláusula ORDER BY, considere o trade-off entre cardinalidade e precisão. Timestamps com precisão de microssegundos geram cardinalidade muito alta (quase um valor único por linha), o que reduz a eficácia do índice primário esparso do ClickHouse. Timestamps arredondados geram cardinalidade mais baixa, o que permite que o índice descarte mais dados, mas você perde precisão em consultas baseadas em tempo.
runnable editable

Foque em consultas individuais, não em médias

Ao depurar o desempenho do ClickHouse, não se baseie em tempos médios de consulta nem em métricas gerais do sistema. Em vez disso, identifique por que consultas específicas estão lentas. Um sistema pode ter um bom desempenho médio, enquanto consultas individuais sofrem com esgotamento de memória, filtragem ineficiente ou operações de alta cardinalidade. Segundo Alexey, CTO da ClickHouse: “A forma correta é se perguntar por que esta consulta em particular foi processada em cinco segundos… Não me importo se a mediana e outras consultas são processadas rapidamente. Só me importo com a minha consulta” Quando uma consulta estiver lenta, não olhe apenas para as médias. Pergunte: “Por que ESTA consulta específica ficou lenta?” e examine os padrões reais de uso de recursos.

Memória e varredura de linhas

A Sentry é uma plataforma de rastreamento de erros voltada para desenvolvedores que processa diariamente bilhões de eventos gerados por mais de 4 milhões de desenvolvedores. O principal insight deles: “É a cardinalidade da chave de agrupamento que vai determinar o uso de memória nesta situação específica” — agregações de alta cardinalidade destroem o desempenho por esgotamento de memória, não por varredura de linhas. Quando as consultas falharem, determine se o problema é de memória (grupos demais) ou de varredura (linhas demais). Uma consulta como GROUP BY user_id, error_message, url_path cria um estado separado na memória para cada combinação única dos três valores. Com uma carga maior de usuários, tipos de erro e caminhos de URL, você pode facilmente gerar milhões de estados de agregação que precisam ser mantidos na memória simultaneamente. Para casos extremos, a Sentry usa amostragem determinística. Uma amostra de 10% reduz o uso de memória em 90%, mantendo cerca de 5% de precisão para a maioria das agregações:
Isso garante que os mesmos usuários apareçam em todas as consultas, fornecendo resultados consistentes em diferentes períodos de tempo. O principal insight é: cityHash64() produz valores de hash consistentes para a mesma entrada, então user_id = 12345 sempre resultará no mesmo valor de hash, garantindo que esse usuário sempre apareça na sua amostra de 10% ou nunca apareça — sem alternar entre consultas.

Otimização de máscara de bits do Sentry

Ao fazer agregações em colunas de alta cardinalidade (como URLs), cada valor único cria um estado de agregação separado na memória, o que acaba esgotando a memória. A solução do Sentry: em vez de agrupar pelas strings reais de URL, agrupe por expressões booleanas que se reduzem a máscaras de bits. Aqui está uma consulta que você pode testar nas suas próprias tabelas, caso essa situação se aplique:
Em vez de armazenar cada string exclusiva na memória, você armazena como inteiros as respostas a perguntas sobre essas strings. O estado de agregação fica pequeno e limitado, independentemente da diversidade dos dados. Da equipe de engenharia da Sentry: “Essas consultas pesadas são mais de 10x mais rápidas e nosso uso de memória é 100x menor (e, mais importante, limitado). Nossos maiores clientes não encontram mais erros ao pesquisar replays, e agora podemos atender clientes de qualquer porte sem esgotar a memória.”

Fontes de vídeo

Leia a seguir:
Última modificação em 29 de junho de 2026