ClickHouse fica mais preguiçoso e mais rápido — introduzindo a otimização de carregamento tardio
(clickhouse.com)- ClickHouse introduziu uma nova técnica de otimização, lazy materialization, aumentando o desempenho de consultas
Top Nem 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
> 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
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
Gosto muito do ClickHouse
Não consigo entender sites em que não dá para rolar
Materialização tardia, 19 anos depois
Não está relacionado com a nova opção de materialização, mas esta parte me chamou a atenção
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
Apesar do drama no aeroporto, estou planejando férias na praia
O ClickHouse é uma obra-prima da engenharia moderna
Fico curioso para saber se alguém já comparou ClickHouse e StarRocks
É impressionante como esses bancos de dados mostram tudo o que os bancos orientados a linhas fazem de errado