6 pontos por GN⁺ 2025-04-24 | 2 comentários | Compartilhar no WhatsApp
  • ClickHouse introduziu uma nova técnica de otimização, lazy materialization, aumentando o desempenho de consultas Top N em até 1.500 vezes
  • A estratégia de ler dados de colunas apenas quando necessário minimiza o I/O de disco
  • Junto com técnicas existentes como armazenamento colunar, índices e PREWHERE, forma uma pilha hierárquica de otimização de I/O
  • Carrega os dados das colunas de forma tardia de acordo com o plano de execução da consulta, sendo especialmente eficaz em consultas com cláusula LIMIT
  • Ativado por padrão, permitindo ganhos de desempenho sem alterações de código

A estratégia de otimização tardia do ClickHouse: Lazy Materialization

Conceito principal

  • O ClickHouse maximiza o desempenho ao evitar ler dados desnecessários
  • Lazy materialization carrega os dados das colunas apenas no momento em que realmente são necessários durante a execução da consulta
  • Funciona de forma independente das técnicas existentes de otimização de I/O, ao mesmo tempo em que oferece ganhos de desempenho complementares

Tecnologias existentes de otimização de I/O

  • Armazenamento colunar: lê apenas as colunas necessárias
  • Sparse Index / Skipping Index / Projections: lê apenas os granules que correspondem às condições filtradas
  • PREWHERE: faz filtragem antecipada em colunas não indexadas
  • Query Condition Cache: armazena em cache os resultados de consultas repetidas para evitar reprocessar o mesmo granule

Como funciona o Lazy Materialization

  • Enquanto as técnicas existentes se concentravam em reduzir I/O por meio de filtragem, lazy materialization adia a leitura até o momento da operação
  • Lê imediatamente apenas as colunas exigidas pela próxima etapa da consulta, e deixa o restante para ser lido após o LIMIT, quando necessário
  • É especialmente eficaz em consultas Top N, nas quais apenas algumas colunas são consultadas, então quase não lê colunas de texto muito grandes

> Essa é uma otimização possível graças ao armazenamento independente por coluna e uma abordagem inviável em bancos de dados baseados em linhas


Exemplo real: conjunto de dados de reviews da Amazon

  • 150M linhas, 70GB sem compressão, 30GB comprimidos

  • Exemplo de consulta Top N:

    SELECT helpful_votes  
    FROM amazon.amazon_reviews  
    ORDER BY helpful_votes DESC  
    LIMIT 3;  
    
    • Tempo de execução: 0,07 s
    • Processamento rápido ao consultar apenas uma coluna
  • Exemplo consultando uma coluna de texto grande:

    SELECT review_body  
    FROM amazon.amazon_reviews  
    FORMAT Null;  
    
    • Tempo de execução: 176 s
    • Embora seja uma única coluna, seus 56GB criam um gargalo de I/O de disco

Comparação de desempenho por camada de otimização aplicada

1. Sem otimização (baseline)

  • Tempo de execução: 219 s
  • Volume processado: 72GB, 150M linhas
  • Lê e ordena todas as colunas

2. Aplicando Primary Key Index

  • Tempo de execução: 96 s
  • Volume processado: 28GB, 53M linhas
  • A filtragem de granules baseada em PK reduz o tempo em mais de 50%

3. Adicionando PREWHERE

  • Tempo de execução: 61 s
  • Volume processado: 16GB
  • Também aplica condições de filtro não indexadas, reduzindo ainda mais o I/O

4. Ativando Lazy Materialization

  • Tempo de execução: 0,18 s
  • Volume processado: 807MB
  • No fim, carrega da coluna grande apenas as 3 linhas realmente necessárias

> No total, mais de 1.200 vezes de ganho de desempenho e mais de 150 vezes de redução no uso de memória


Também é eficaz em consultas Top N sem filtro

  • Em uma consulta de ordenação completa sem filtro:

    SELECT helpful_votes, product_title, review_headline, review_body  
    FROM amazon.amazon_reviews  
    ORDER BY helpful_votes DESC  
    LIMIT 3;  
    
  • Antes de lazy materialization: 219 s

  • Depois de lazy materialization: 0,139 s

  • 1.576 vezes mais rápido, 40 vezes menos I/O e 300 vezes menos uso de memória


Verificando o plano de execução

EXPLAIN actions = 1  
SELECT helpful_votes, product_title, review_headline, review_body  
FROM amazon.amazon_reviews  
ORDER BY helpful_votes DESC  
LIMIT 3  
SETTINGS query_plan_optimize_lazy_materialization = true;  
  • Resultado:
Lazily read columns: review_headline, review_body, product_title   
  Limit                    
    Sorting                             
      ReadFromMergeTree  
  • As colunas grandes só são carregadas após a ordenação e o LIMIT

Conclusão

  • Conclusão da pilha de otimização de I/O do ClickHouse: Index → PREWHERE → Lazy Materialization
  • Sem alterar código, apenas pela forma de execução da consulta, o desempenho melhora centenas ou milhares de vezes
  • Ideal especialmente para padrões Top N, colunas grandes e consultas com LIMIT
  • Ativado por padrão, sendo aplicado automaticamente sem necessidade de configuração manual pelo usuário

> O mesmo SQL, a mesma máquina, resultado diferente
> Mais rápido = menos leitura = ClickHouse

2 comentários

 
zihado 2025-04-24

> Fico curioso para saber se alguém já comparou ClickHouse e StarRocks; há alguns meses, o desempenho de joins do StarRocks parecia melhor
https://d2.naver.com/helloworld/1168674

 
GN⁺ 2025-04-24
Comentários do Hacker News
  • Essa otimização deve proporcionar ganhos dramáticos de velocidade ao extrair amostras aleatórias de grandes conjuntos de dados, especialmente quando as colunas desejadas podem conter valores grandes

    • A receita SQL básica usa a cláusula LIMIT para determinar quais linhas serão incluídas na amostra
    • A nova otimização promete adiar a leitura das colunas grandes até que a cláusula LIMIT filtre o conjunto de dados para um pequeno número de linhas
    • Fico curioso para saber se alguém consegue verificar se essa otimização acelera essas consultas no ClickHouse
  • Gosto muito do ClickHouse

    • Descobri recentemente e ele parece um sopro de ar fresco em comparação com soluções ineficientes para análise
    • É muito rápido e a CLI também é agradável de usar
  • Não consigo entender sites em que não dá para rolar

    • Você rola um pouco e ele pula de volta para cima, ficando impossível de usar
  • Materialização tardia, 19 anos depois

    • Link relacionado fornecido
  • Não está relacionado com a nova opção de materialização, mas esta parte me chamou a atenção

    • A consulta ordena 150 milhões de valores e retorna os 3 primeiros em 70 milissegundos
    • Preciso atualizar meu modelo mental sobre o que é uma consulta lenta em hardware e software modernos
    • Ordenar 150 milhões de inteiros em 70 milissegundos não é impressionante
    • O uso de memória no pico é de 3,59 MiB
    • Artigo excelente, explicado com clareza e com bons diagramas
  • Se o ClickHouse tivesse uma versão nativa para Windows sem precisar de WSL ou de uma máquina virtual Linux, seria mais popular que o DuckDB

    • Um dos motivos de o MySQL ter sido mais popular que o PostgreSQL era o fato de o MySQL ter um instalador para Windows
  • Apesar do drama no aeroporto, estou planejando férias na praia

    • As informações técnicas e os diagramas eram de altíssimo nível, mas a presença de uma história deixou tudo ainda melhor
  • O ClickHouse é uma obra-prima da engenharia moderna

    • Atenção absoluta ao desempenho
  • Fico curioso para saber se alguém já comparou ClickHouse e StarRocks

    • Alguns meses atrás, o desempenho de joins do StarRocks parecia melhor
  • É impressionante como esses bancos de dados mostram tudo o que os bancos orientados a linhas fazem de errado

    • Não dá para chegar perto dessa velocidade com uma estrutura de índice btree
    • É impressionante ver o quão rápidas as máquinas modernas são
    • Parece que nem compactaram o conjunto de dados corretamente
    • Ler os dados é mais lento do que descompactá-los
    • Isso me lembrou um artigo da Cloudflare, com a ideia de que criptografia é gratuita
    • É surpreendente usar o mecanismo de computação (chdb)