DuckDB

Imagine conseguir analisar milhões de registros em segundos utilizando apenas SQL, sem instalar um servidor de banco de dados, sem importar arquivos e consumindo pouca memória.

Parece bom demais para ser verdade?

Essa é exatamente a proposta do DuckDB.

Criado por pesquisadores da Universidade de Amsterdã (CWI) e do MIT, o DuckDB foi desenvolvido para resolver um problema muito comum: realizar análises analíticas (OLAP) de forma rápida, simples e eficiente diretamente na máquina do analista.

Nos últimos anos ele se tornou uma das ferramentas favoritas de Cientistas de Dados, Engenheiros de Dados e Analistas de BI, sendo integrado a projetos em Python, R, Polars, Pandas, Apache Arrow, Jupyter e Data Lakes baseados em Parquet.

Neste guia você aprenderá desde os primeiros comandos até recursos avançados utilizados em projetos reais.

O que torna o DuckDB tão especial?

O DuckDB foi projetado especificamente para consultas analíticas.

Enquanto bancos transacionais, como PostgreSQL e MySQL, são excelentes para registrar operações do dia a dia, o DuckDB foi otimizado para responder perguntas sobre grandes volumes de dados.

Entre seus diferenciais estão:

  • Não precisa de servidor dedicado.
  • Funciona como uma biblioteca embarcada (embedded).
  • Armazenamento colunar e execução vetorizada.
  • Paralelismo automático.
  • Leitura direta de CSV, JSON e Parquet.
  • Integração com Excel, Pandas, Polars e Apache Arrow.
  • Execução de SQL ANSI.
  • Excelente desempenho para consultas agregadas.
  • Suporte a funções analíticas (Window Functions).
  • Instalação simples.

Instalando

Python

pip install duckdb

CLI

duckdb

Abrindo um banco

.open analytics.duckdb

Criando tabelas

CREATE TABLE vendas (

id INTEGER,

cliente VARCHAR,

produto VARCHAR,

categoria VARCHAR,

cidade VARCHAR,

valor DECIMAL(10,2),

data_venda DATE

);

Inserindo registros

INSERT INTO vendas VALUES

(1,'João','Notebook','Informática','São Carlos',5200,'2026-01-10'),

(2,'Maria','Mouse','Periféricos','Campinas',120,'2026-01-11'),

(3,'Pedro','Notebook','Informática','São Paulo',5100,'2026-01-13');

Visualizando dados

SELECT *

FROM vendas;

Importando arquivos

CSV

SELECT *

FROM read_csv('vendas.csv');

Parquet

SELECT *

FROM read_parquet('vendas.parquet');

Todos os arquivos da pasta

SELECT *

FROM read_parquet('dados/*.parquet');

JSON

SELECT *

FROM read_json('pedidos.json');

Filtrando dados

SELECT *

FROM vendas

WHERE valor > 1000;

Múltiplas condições

SELECT *

FROM vendas

WHERE cidade='São Carlos'

AND categoria='Informática';

Ordenação

SELECT *

FROM vendas

ORDER BY valor DESC;

LIMIT

SELECT *

FROM vendas

LIMIT 10;

DISTINCT

SELECT DISTINCT cidade

FROM vendas;

GROUP BY

SELECT

cidade,

SUM(valor)

FROM vendas

GROUP BY cidade;

HAVING

SELECT

cidade,

SUM(valor)

FROM vendas

GROUP BY cidade

HAVING SUM(valor)>10000;

CASE

SELECT

cliente,

CASE

WHEN valor>5000 THEN 'Premium'

ELSE 'Padrão'

END categoria_cliente

FROM vendas;

JOIN

SELECT

v.cliente,

c.estado

FROM vendas v

JOIN clientes c

ON c.id=v.cliente_id;

LEFT JOIN

SELECT *

FROM clientes c

LEFT JOIN vendas v

ON c.id=v.cliente_id;

UNION

SELECT *

FROM vendas2025

UNION ALL

SELECT *

FROM vendas2026;

Funções de agregação

COUNT(*)

SUM(valor)

AVG(valor)

MIN(valor)

MAX(valor)

MEDIAN(valor)

STDDEV(valor)

Window Functions

Ranking

SELECT

cliente,

valor,

RANK() OVER(ORDER BY valor DESC)

FROM vendas;

Running Total

SELECT

data_venda,

SUM(valor)

OVER(

ORDER BY data_venda

)

FROM vendas;

Média móvel

SELECT

data_venda,

AVG(valor)

OVER(

ORDER BY data_venda

ROWS BETWEEN 2 PRECEDING

AND CURRENT ROW

)

FROM vendas;

Trabalhando com datas

Ano

SELECT YEAR(data_venda)

FROM vendas;

Mês

SELECT MONTH(data_venda)

FROM vendas;

Dia

SELECT DAY(data_venda)

FROM vendas;

Agrupando por mês

SELECT

MONTH(data_venda),

SUM(valor)

FROM vendas

GROUP BY MONTH(data_venda);

Strings

Maiúsculas

UPPER(cliente)

Minúsculas

LOWER(cliente)

Concatenação

CONCAT(nome,' ',sobrenome)

Substring

SUBSTRING(nome,1,5)

Trabalhando com NULL

COALESCE(desconto,0)
IFNULL(desconto,0)

CTE

WITH faturamento AS (

SELECT

cidade,

SUM(valor) total

FROM vendas

GROUP BY cidade

)

SELECT *

FROM faturamento

ORDER BY total DESC;

Views

CREATE VIEW vendas_sp AS

SELECT *

FROM vendas

WHERE cidade='São Paulo';

Exportando resultados

CSV

COPY (

SELECT *

FROM vendas

)

TO 'resultado.csv'

(FORMAT CSV, HEADER);

Parquet

COPY vendas

TO 'vendas.parquet'

(FORMAT PARQUET);

EXPLAIN

EXPLAIN

SELECT *

FROM vendas

WHERE valor>1000;

Excelente para entender como o DuckDB executa cada consulta.

PIVOT

PIVOT vendas

ON categoria

USING SUM(valor);

Ideal para criar tabelas dinâmicas usando SQL.

UNPIVOT

UNPIVOT vendas

ON janeiro,

fevereiro,

março

INTO

NAME mes

VALUE faturamento;

Funções estatísticas

CORR()

COVAR_POP()

MEDIAN()

MODE()

QUANTILE()

PERCENTILE_CONT()

Muito úteis em Ciência de Dados.

Trabalhando com múltiplos arquivos

SELECT *

FROM read_parquet(

'datalake/**/*.parquet'

);

O DuckDB consulta centenas de arquivos simultaneamente.

Integrando com Python

import duckdb

df = duckdb.sql("""

SELECT

categoria,

SUM(valor)

FROM read_parquet('dados/*.parquet')

GROUP BY categoria

""").df()

print(df)

O resultado já retorna como um DataFrame do Pandas.

Casos de uso reais

O DuckDB é uma excelente escolha para:

  • Exploração de grandes conjuntos de dados.
  • Processamento de arquivos Parquet em Data Lakes.
  • Construção de notebooks analíticos.
  • Preparação de dados para Machine Learning.
  • Validação de pipelines de Engenharia de Dados.
  • Criação de datasets para dashboards.
  • Análise de logs em JSON.
  • Consolidação de planilhas Excel.
  • Integração com Polars, Pandas e Apache Arrow.
  • Desenvolvimento local antes da execução em ambientes distribuídos.

Dicas de desempenho

  • Prefira arquivos Parquet para grandes volumes de dados.
  • Selecione apenas as colunas necessárias em vez de usar SELECT *.
  • Utilize filtros (WHERE) o mais cedo possível.
  • Aproveite o particionamento de diretórios para reduzir leituras.
  • Use EXPLAIN para entender planos de execução.
  • Prefira funções analíticas (OVER) em vez de múltiplas subconsultas quando apropriado.

Conclusão

O DuckDB não é apenas mais um banco de dados: ele representa uma mudança na forma de trabalhar com análise de dados. Sua combinação de simplicidade, desempenho e integração com formatos modernos como Parquet, JSON e Apache Arrow permite que analistas e engenheiros concentrem seus esforços na geração de valor, e não na configuração de infraestrutura.

Dominar seus comandos fundamentais — desde consultas básicas até funções analíticas, PIVOT, CTEs, exportação de resultados e integração com Python — torna o DuckDB uma ferramenta extremamente versátil para projetos de Ciência de Dados, Engenharia de Dados e Business Intelligence.

Se você trabalha diariamente com dados, vale a pena incorporar o DuckDB ao seu conjunto de ferramentas. Em muitos cenários, ele pode reduzir significativamente o tempo entre a pergunta de negócio e a resposta baseada em evidências.