DuckDB e Polars: a revolução in-process
⏱ 12 min·⭐ 55 XP
Pré-requisitos (0/1)0%
- ⬜🎼 Airflow vs Dagster vs Prefect: qual orquestrador(Data Engineering Moderna)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
DuckDB exemplo
| Ferramenta | Interface | Brilha quando | Limite |
|---|---|---|---|
| Banco analítico embutido | SQL | Consulta agregada sobre arquivos, sem servidor | Uma máquina só |
| Biblioteca de dataframe colunar | API encadeada | Transformação programática com tipos e avaliação tardia | Uma máquina só |
| Dataframe clássico em memória | API imperativa | Ecossistema enorme e familiaridade | Tudo em memória, sem paralelismo real |
| Motor distribuído | SQL ou API | Volume que não cabe numa máquina | Complexidade de operação alta demais para o caso comum |
FerramentaBanco analítico embutido
InterfaceSQL
Brilha quandoConsulta agregada sobre arquivos, sem servidor
LimiteUma máquina só
FerramentaBiblioteca de dataframe colunar
InterfaceAPI encadeada
Brilha quandoTransformação programática com tipos e avaliação tardia
LimiteUma máquina só
FerramentaDataframe clássico em memória
InterfaceAPI imperativa
Brilha quandoEcossistema enorme e familiaridade
LimiteTudo em memória, sem paralelismo real
FerramentaMotor distribuído
InterfaceSQL ou API
Brilha quandoVolume que não cabe numa máquina
LimiteComplexidade de operação alta demais para o caso comum
-- Ler Parquet diretamente do S3
SELECT country, COUNT(*), SUM(revenue)
FROM 's3://bucket/orders/*.parquet'
WHERE date >= '2026-01-01'
GROUP BY country
ORDER BY 3 DESC;
-- JOIN com CSV local
SELECT u.name, COUNT(o.id)
FROM 'users.csv' u
JOIN 'orders.csv' o ON o.user_id = u.id
GROUP BY u.name;
-- Em Python: 0-copy com pandas
import duckdb, pandas as pd
df = pd.read_csv('orders.csv')
result = duckdb.sql('SELECT country, COUNT(*) FROM df GROUP BY country').df()Polars exemplo
import polars as pl
# Lazy evaluation — optimizer aplica predicate pushdown
df = (
pl.scan_parquet('orders/*.parquet') # lazy, não lê ainda
.filter(pl.col('date') >= '2026-01-01')
.group_by('country')
.agg([
pl.count().alias('orders'),
pl.col('revenue').sum().alias('revenue'),
])
.sort('revenue', descending=True)
.collect() # execute agora
)
# SQL mode também disponível
ctx = pl.SQLContext(orders=df)
result = ctx.execute('SELECT country, SUM(revenue) FROM orders GROUP BY country').collect()Quiz rápido
Que mudança tornou viável processar volumes analíticos numa única máquina?
Quando usar cada
💡
DuckDB: workflow SQL-first, integração com Parquet, notebooks analíticos. Polars: workflow DataFrame Python, ML preprocessing, data science. Os dois combinam: DuckDB pra query complexa, Polars pra transformação Pythonic. Ambos 10-100x pandas em dataset médio.
Perguntas frequentes
❓ Quando usar banco analítico embarcado em vez de armazém?
Quando o dado cabe na máquina — e cabe mais do que se imagina, porque formato colunar comprime muito. Para análise até dezenas de gigabytes, o embarcado costuma ser mais rápido que enviar para o armazém, e não tem custo por consulta nem espera de fila.
❓ Substituir pandas por biblioteca colunar vale o esforço?
Vale quando o gargalo é memória ou tempo em conjunto grande: a execução em colunas com avaliação tardia usa menos memória e paraleliza. Não vale por moda em conjunto pequeno, onde a diferença é imperceptível e o custo é reescrever código que funciona.
❓ O embarcado serve para produção?
Serve para transformação e análise em processo, dentro de um pipeline ou de uma aplicação analítica — não como banco compartilhado com escrita concorrente. Confundir os dois papéis é o erro que aparece quando o segundo processo tenta escrever.
Fixando
Quiz rápido
Quando ainda vale usar um sistema distribuído em vez de processar localmente?
Quiz rápido
Qual é a vantagem de consultar arquivos diretamente, sem carregá-los num banco?
Terminou de ler?
Marcar como concluído registra o XP, mantém sua sequência e coloca 3 cartas deste módulo na fila de revisão espaçada.
Próximos passos sugeridos
Temas deste módulo
Discussão
Carregando comentários…