Pular para o conteúdo principal

DuckDB vs SQLite: Uma comparação completa de bancos de dados

Aprenda as principais diferenças entre DuckDB e SQLite e como eles se comparam entre si.
Atualizado 7 de nov. de 2025  · 15 min lido

No gerenciamento moderno de dados, bancos de dados incorporados leves têm um papel importante em aplicativos, fluxos de trabalho e análises. Dois sistemas que sempre comparam sãoo DuckDB e o SQLite, que são do tipo ”. 

Ambos são bancos de dados incorporados, mas têm finalidades diferentes: O SQLite é ótimo pra cargas de trabalho transacionais, enquanto o DuckDB é mais legal pra consultas analíticas.

Neste artigo comparativo, vamos ver como os dois bancos de dados são diferentes um do outro.

Em resumo: DuckDB vs SQLite

Aqui tá uma tabela comparativa mostrando as semelhanças e diferenças entre o DuckDB e o SQLite. Para mais detalhes, dá uma olhada nas explicações ao longo deste artigo. 

Categoria SQLite DuckDB
Ano de lançamento 2000 2019
Objetivo principal Banco de dados leve e transacional (OLTP) Banco de dados analítico incorporado (OLAP)
Modelo de armazenamento Baseado em linhas Colunar
Tipo de carga de trabalho OLTP (inserir, atualizar, excluir, pesquisas pontuais) OLAP (agregações, junções, varreduras)
Execução da consulta Baseado em iterador (linha por vez) Vetorizado (lote por vez)
Força de desempenho Ótimo pra transações pequenas e frequentes Ótimo para consultas analíticas em grandes conjuntos de dados
Modelo de Concorrência Um único autor, vários leitores Execução paralela de consultas entre núcleos de CPU
Tamanho dos dados Otimizado para conjuntos de dados pequenos a médios Lida com conjuntos de dados maiores que a memória (execução fora do núcleo)
Suporte a formatos de arquivo Apenas arquivo SQLite proprietário Suporte nativo para Parquet, Arrow e CSV
Acesso a dados externos Precisa importar antes de fazer a consulta Consultar arquivos diretamente sem importar
Integrações Amplo suporte a linguagens (C, Python, Java, PHP, etc.) Integração profunda com ciência de dados (Python, R, pandas, Jupyter)
Integração na nuvem Recursos locais em primeiro lugar, recursos limitados na nuvem Integração nativa com S3, Azure e GCS para Parquet/Arrow
Transações e ACID Totalmente compatível com ACID ACID em um único processo, menos robusto para gravações simultâneas
Configuração e dependências Sem precisar de configuração, biblioteca C única Instalação simples, mas com dependências opcionais (Arrow, Pandas)
Recursos SQL Focado em CRUD; suporte parcial a SQL analítico Suporte robusto a ANSI SQL com análises avançadas (CTEs, funções de janela)
Casos de uso típicos Aplicativos móveis, dispositivos IoT, caches locais Ciência de dados, painéis de BI, pipelines ETL
Escalabilidade Limitado à execução em thread único Paralelismo multicore e spill de disco para grandes cargas de trabalho
Manutenção Mínimo; VACUUM ocasional para liberar espaço Mínimo; gerenciamento de parquet particionado para eficiência
Ideal para Aplicativos integrados que precisam de armazenamento local confiável Fluxos de trabalho analíticos em Python/R ou em contextos sem servidor
Exemplo de contexto de consulta SELECT * FROM usuários WHERE id=1; SELECT região, AVG(valor) FROM vendas GROUP BY região;

O que é SQLite?

O SQLite é um dos bancos de dados mais usados no mundo. Lançado em 2000, o SQLite foi projetado como um banco de dados leve e sem servidor.

Aqui estão algumas das principais características:

  • Autônomo e sem servidor
  • Configuração sem necessidade de ajustes
  • Totalmente em conformidade com ACID
  • Armazenamento orientado por linha

Por causa da sua arquitetura leve, ele pode ser usado nos seguintes casos:

  • Aplicativos móveis (Android, iOS)
  • Software para computador
  • Sistemas incorporados, como dispositivos IoT

O ponto forte do SQLite é a simplicidade e a confiabilidade. Os desenvolvedores podem enviar um único banco de dados baseado em arquivo com seu aplicativo sem se preocupar com dependências externas.

O que é o DuckDB?

O DuckDB é frequentemente chamado de SQLite para análises. Lançado em 2019, o DuckDB foi desenvolvido no CWI. O principal objetivo de usar o DuckDB era ter uma solução de banco de dados OLAP em processo. OLAP em processo.

Aqui estão algumas das principais características:

  • Formato de armazenamento em colunas
  • Otimizado para cargas de trabalho OLAP
  • Execução de consulta vetorizada
  • Projeto incorporado em processo
  • Suporte direto para formatos de arquivo como Parquet e Arrow

Alguns casos de uso típicos incluem:

  • Análise interativa
  • Fluxos de trabalho de ciência de dados (Python, R, Jupyter)
  • Pipelines ETL leves

O ponto principal de usar o DuckDB é que ele oferece o poder dos bancos de dados analíticos (como o Snowflake ou BigQuery) em um pacote integrado.

DuckDB vs SQLite: Principais diferenças e semelhanças

1. Instalação e dependências

SQLite

O SQLite é famoso por não ter dependências. Ele é compilado em uma única biblioteca C que pode ser incluída em praticamente qualquer aplicativo.

A instalação é bem simples e pode ser feita baixando o programa do site do SQLite.

A portabilidade é um dos seus maiores pontos fortes: funciona da mesma forma no Windows, macOS, Linux, iOS e Android, quase sem esforço extra.

DuckDB

O DuckDB também é fácil de instalar, mas é distribuído como binários separados ou pacotes Python/R em vez de vir pré-instalado em todos os lugares.

Tem mais algumas dependências, principalmente quando se habilita integrações com Apache Arrow, Parquet ou Pandas.

A pegada ainda é pequena, mas comparado com o SQLite, o DuckDB precisa de um pouco mais de configuração se você quiser funcionalidades avançadas, como conectores de armazenamento em nuvem ou integração com ferramentas de ciência de dados.

2. Formatos e arquitetura de armazenamento

SQLite 

Armazena dados em um formato baseado em linhas, otimizado para OLTP (Processamento de Transações Online) , como inserções, atualizações e exclusões.

Recuperar uma linha inteira é rápido, mas consultas analíticas que examinam apenas algumas colunas em milhões de linhas podem ficar lentas porque dados desnecessários são lidos.

DuckDB

O DuckDB usa um mecanismo de armazenamento em colunas, feito especialmente para OLAP (Processamento Analítico Online).

O formato colunar significa que as consultas que agregam grandes conjuntos de dados (por exemplo, AVG(sales) ou COUNT(*)) são muito mais rápidas, já que só as colunas relevantes são lidas na memória.

Também permite uma melhor compressão e execução vetorizada para maior velocidade.

Exemplo: Uma consulta SELECT * FROM sales WHERE customer_id=123 é mais rápida no SQLite, enquanto SELECT AVG(amount) FROM sales GROUP BY region é bem mais rápida no DuckDB.

3. Cargas de trabalho transacionais versus analíticas

Os dois bancos de dados também são diferentes em termos de carga de trabalho:

  • OLTP (Transactional): Operações curtas e frequentes (por exemplo, aplicativos bancários, perfis de usuário, sistemas de ponto de venda). Suas prioridades são baixa latência, integridade dos dados e acesso simultâneo.
  • OLAP (Analítico): Consultas complexas em grandes conjuntos de dados (por exemplo, painéis, ferramentas de BI, análise de dados ad hoc). As prioridades dele são a taxa de transferência, o desempenho da digitalização e a velocidade de agregação.

SQLite

O SQLite é otimizado para OLTP (inserção, atualização, exclusão, pesquisas pontuais).

Por exemplo:

  • Apps móveis que guardam dados offline.
  • Dispositivos IoT registrando as interações dos usuários.
  • Caches locais em aplicativos de desktop.

DuckDB

O DuckDB é otimizado para OLAP (agregações, junções, varreduras).

Por exemplo:

  • Cientistas de dados fazendo agregações em arquivos Parquet/CSV.
  • Painéis Painéis de BI onde as consultas resumem milhões de linhas.
  • Pipelines ETL/ELT que precisam de transformações leves na memória.

4. Suporte e sintaxe SQL

A seguir, vamos dar uma olhada na sintaxe SQL deles. Ambos implementam um grande subconjunto do padrão SQL com extensões; nenhum deles é totalmente compatível com ANSI.

SQLite

  • Suporta grande parte do padrão SQL, mas deixa de fora construções analíticas avançadas.
  • Ótimo para operações CRUD e junções mais simples.
  • Suporta funções de janela e CTEs, mas não tem recursos analíticos mais avançados, como GROUPING SETS e algumas extensões agregadas.

Aqui tá como a sintaxe fica:

CREATE TABLE sales (
    id INTEGER PRIMARY KEY,
    product TEXT,
    amount REAL,
    sale_date TEXT
);

DuckDB

  • Muito mais próximo da conformidade com ANSI SQL, com forte suporte para funções de janela, CTEs, agregações e operações de conjunto.
  • Feito pra ser tipo um PostgreSQL leve pra análise de dados.
  • A integração com o Arrow e o Pandas permite executar SQL diretamente em conjuntos de dados externos sem precisar importá-los primeiro.

Aqui está um exemplo semelhante de como é a sintaxe para o DuckDB:

CREATE TABLE sales (
    id INTEGER,
    product VARCHAR,
    amount DOUBLE,
    sale_date DATE
);

SQLite vs DuckDB: Arquitetura e filosofia de design fundamentais

Em termos de arquitetura básica, o SQLite e o DuckDB são bancos de dados incorporados e em processo. Mas, suas filosofias de design são diferentes. 

O SQLite prioriza a simplicidade e a confiabilidade das transações, enquanto o DuckDB é otimizado para cargas de trabalho analíticas e integração moderna com ciência de dados.

1. Arquitetura de armazenamento

Primeiro, os dois bancos de dados têm uma arquitetura de armazenamento diferente.

SQLite

O SQLite é baseado em linhas, o que é ótimo para acesso transacional. Isso quer dizer que linhas inteiras são guardadas juntas no disco.

Esse design é bom para cargas de trabalho transacionais (OLTP), porque inserir, atualizar ou recuperar um único registro normalmente só precisa acessar uma linha.

Os aplicativos que precisam de acesso rápido e consistente a registros individuais, como perfis de usuários ou detalhes de pedidos, vão funcionar bem nesse modelo.

DuckDB

O DuckDB usa um formato em colunas, que foi feito pra dar uma olhada rápida em bilhões de linhas. Ter um formato em colunas significa juntar os valores da mesma coluna no disco e na memória.

O armazenamento em colunas permite consultas analíticas super eficientes (OLAP), já que agregações, filtros e varreduras geralmente só precisam acessar um subconjunto de colunas.

As técnicas de compressão funcionam melhor nas colunas, reduzindo o uso de memória e armazenamento e melhorando o desempenho da varredura.

2. Métodos de processamento de consultas

Depois, vamos precisar ver como cada um deles processa as consultas.

Em geral, o modelo do SQLite é ajustado para simplicidade e correção transacional, enquanto o mecanismo vetorizado do DuckDB é projetado para rendimento e desempenho analítico.

SQLite

O SQLite usa um modelo tradicional baseado em iterador, processando uma linha de cada vez através do pipeline de consulta.

Essa abordagem de execução linha por linha é leve e se encaixa bem com cargas de trabalho transacionais, onde as consultas geralmente envolvem pequenos conjuntos de dados e inserções ou atualizações frequentes.

Mas, os gargalos de desempenho aparecem quando as consultas precisam examinar grandes conjuntos de dados, já que a avaliação linha por linha adiciona sobrecarga.

DuckDB

O DuckDB usa execução de consulta vetorizada, processando lotes de linhas (vetores) de uma vez só, em vez de uma de cada vez.

Essa abordagem minimiza a sobrecarga da CPU, aproveita melhor os caches modernos da CPU e permite o paralelismo SIMD (Single Instruction, Multiple Data, ou Instrução Única, Dados Múltiplos).

A execução vetorizada é especialmente boa para análises: operações como agregações, junções e filtros funcionam bem mais rápido em grandes volumes de dados.

No DuckDB, a consulta a seguir aproveita o armazenamento em colunas e o processamento vetorizado, tornando-a significativamente mais rápida.

SELECT region, AVG(amount)
FROM sales
GROUP BY region;

3. Arquitetura de banco de dados em processo

Por fim, o SQLite e o DuckDB são bancos de dados incorporados, ou seja, eles funcionam dentro do processo do aplicativo host, em vez de como um servidor de banco de dados separado.

Essa arquitetura acaba com a latência da rede, simplifica a implantação e reduz a carga operacional de gerenciar serviços externos.

Isso faz com que eles sejam:

  • Fácil de distribuir
  • Fácil de implementar
  • Baixa latência (sem sobrecarga cliente-servidor)

SQLite 

O SQLite foi o primeiro a ter a ideia de ser um banco de dados “sem servidor”. Isso quer dizer que seus aplicativos se conectam direto à biblioteca deles, e todas as consultas rolam dentro do próprio aplicativo.

DuckDB 

O DuckDB segue um design semelhante em processo, mas aplica-o a contextos analíticos.

Para evitar o overhead de ativar mecanismos analíticos externos, o DuckDB aproveita os ambientes de ciência de dados (Python, R ou até mesmo notebooks Jupyter) executando consultas neles.

Análise de desempenho e benchmarking do DuckDB vs SQLite

O desempenho é um dos principais diferenciais entre o DuckDB e o SQLite. Embora ambos sejam bancos de dados incorporados, suas prioridades de design influenciam como eles se comportam sob diferentes cargas de trabalho. 

Em geral, o SQLite tem um ótimo desempenho em casos de uso transacional, enquanto o DuckDB se sai bem em contextos analíticos.

1. Desempenho da consulta analítica

DuckDB:

  • Supera o SQLite em agregações, junções e agrupamentos.
  • Pode consultar arquivos Parquet/Arrow diretamente.
  • O DuckDB foi feito pra executar consultas analíticas e costuma ser melhor que o SQLite quando se trata de processar grandes conjuntos de dados.

Vamos ver como isso pode ser testado por meio de uma consulta de agregação.

Imagina que a gente tem um conjunto de dados de vendas (sales.csv) com 10 milhões de linhas que têm order_id, customer_id, amount e date.

SQLite (Python):

Pra rodar essa consulta no SQLite usando Python, a gente vai precisar carregar o CSV em um DataFrame e ler em um banco de dados de conexão SQLite3, e rodar nossa consulta SQL dentro dele.

Aqui está um exemplo de código:

import sqlite3
import pandas as pd

# Load CSV into SQLite
df = pd.read_csv("sales.csv")
conn = sqlite3.connect("sales.db")
df.to_sql("sales", conn, if_exists="replace", index=False)

# Run a GROUP BY query directly on the imported table
cursor = conn.execute("""
    SELECT customer_id, SUM(amount) AS total_spent
    FROM sales
    GROUP BY customer_id
    ORDER BY total_spent DESC
    LIMIT 5
""")
print(cursor.fetchall())

DuckDB (Python):

Para fazer uma consulta parecida usando o DuckDB no Python, são necessários menos passos. Não é preciso um DataFrame.

Aqui está um exemplo de código:

import duckdb

con = duckdb.connect()
# Run a GROUP BY query directly on the CSV file
result = con.execute(""" SELECT customer_id, SUM(amount) AS total_spent FROM read_csv_auto('sales.csv') GROUP BY customer_id ORDER BY total_spent DESC LIMIT 5 """).fetchdf()
print(result)

2. Desempenho da carga de trabalho transacional

Em termos de carga de trabalho transacional, cada banco de dados tem seus casos de uso exclusivos.

O SQLite é otimizado para cargas de trabalho com muitas transações e consultas pontuais. Ele lida com operações frequentes de INSERT, UPDATE e DELETE com uma sobrecarga muito baixa, tornando-o ideal para sistemas transacionais incorporados.

O SQLite suporta inserções em massa de forma eficiente usando transações e tem um bom desempenho quando pequenas atualizações são necessárias com frequência.

Já o DuckDB se concentra em consultas analíticas depois que os dados são inseridos, em vez de atualizações transacionais de alta frequência.

3. Escalabilidade e uso de recursos

SQLite

O SQLite é leve e costuma ser usado para conjuntos de dados pequenos a médios. Uma única consulta rola em um thread e o SQLite usa um modelo de gravação única com leituras simultâneas; ele não faz paralelização de um único SELECT, o que pode limitar o rendimento analítico.

DuckDB

O DuckDB suporta paralelismo multi-core e consultas maiores que a memória. Ele se adapta usando execução paralela e pode usar o disco quando necessário, permitindo análises fora do núcleo.

Isso permite analisar conjuntos de dados que ultrapassam em muito a memória do sistema, mantendo um desempenho próximo à execução na memória.

4. Formato de arquivo e desempenho de E/S

SQLite

O SQLite guarda os dados num formato próprio baseado em linhas, que é portátil e estável, mas não tem interoperabilidade direta com os formatos analíticos modernos. Os dados muitas vezes precisam ser importados para o SQLite antes que as consultas possam ser executadas, o que adiciona uma sobrecarga extra de E/S.

DuckDB

O DuckDB suporta nativamente vários formatos de arquivo, incluindo Parquet, Arrow e CSV, permitindo consultar dados diretamente sem conversão (por exemplo, SELECT … FROM 'file.parquet').

Isso elimina a sobrecarga de ETL e acelera a análise, lendo apenas os dados necessários de formatos colunares como o Parquet.

Ingestão de dados e interoperabilidade no DuckDB vs SQLite

Os bancos de dados são geralmente usados para armazenar grandes quantidades de dados. A seguir, vamos ver como cada um deles se sai em termos de capacidade de ingestão e interoperabilidade.

1. Formatos de arquivo compatíveis e ingestão

DuckDB

O DuckDB oferece ingestão nativa de Parquet, Arrow e CSV. Ele pode executar consultas SQL diretamente no Parquet sem importá-lo para um arquivo de banco de dados.

import duckdb

con = duckdb.connect()
result = con.execute("""
    SELECT customer_id, SUM(amount) AS total_spent
    FROM 'sales.parquet'
    GROUP BY customer_id
    ORDER BY total_spent DESC
    LIMIT 5
""").fetchdf()

print(result)

SQLite

O SQLite precisa importar dados externos para o seu formato de armazenamento antes que as consultas possam ser executadas.

import sqlite3
import pandas as pd

# Load CSV into pandas first
df = pd.read_csv("sales.csv")

# Store into SQLite
conn = sqlite3.connect("sales.db")
df.to_sql("sales", conn, if_exists="replace", index=False)

# Query the imported table
cursor = conn.execute("""
    SELECT customer_id, SUM(amount) AS total_spent
    FROM sales
    GROUP BY customer_id
    ORDER BY total_spent DESC
    LIMIT 5
""")

print(cursor.fetchall())

2. Integração com ferramentas de ciência de dados

DuckDB

O DuckDB tem uma integração bem forte com o pandas, o R e o Jupyter, e se conecta direto com os DataFrame do pandas, permitindo que você os trate como tabelas SQL:

import duckdb
import pandas as pd

# Example pandas DataFrame
df = pd.DataFrame({
    "customer_id": [1, 2, 1, 3],
    "amount": [100, 200, 150, 300]
})

# Query DataFrame directly with DuckDB
result = duckdb.query("""
    SELECT customer_id, AVG(amount) as avg_spent
    FROM df
    GROUP BY customer_id
""").to_df()

print(result)

SQLite

O SQLite funciona com várias linguagens de programação, mas não é tão focado em ciência de dados.

Por exemplo, o SQLite também pode interagir com o pandas, mas geralmente precisa de mais código padrão.

import sqlite3
import pandas as pd

conn = sqlite3.connect(":memory:")
df = pd.DataFrame({
    "customer_id": [1, 2, 1, 3],
    "amount": [100, 200, 150, 300]
})

df.to_sql("sales", conn, index=False, if_exists="replace")

# Query back into pandas
query = "SELECT customer_id, AVG(amount) as avg_spent FROM sales GROUP BY customer_id"
result = pd.read_sql_query(query, conn)

print(result)

3. Ligações de linguagem e APIs

SQLite

O SQLite existe desde 2000, então suas ligações são super maduras. Como é só uma pequena biblioteca C, a maioria das linguagens tem suporte oficial ou da comunidade.

Alguns exemplos incluem: C, Python (sqlite3), Java, PHP e muito mais.

DuckDB

O DuckDB é bem mais recente, mas foi feito pensando em ciência de dados e fluxos de trabalho analíticos. Suas ligações são menos, mas muito amigáveis para a ciência de dados.

Alguns exemplos incluem: Python, R, C++, JavaScript bindings.

Casos de uso e áreas de aplicação

Embora tanto o SQLite quanto o DuckDB sejam bancos de dados leves e incorporados, eles têm finalidades bem diferentes. 

O SQLite é ótimo pra contextos transacionais e de nível de aplicativo, enquanto o DuckDB é ideal pra cargas de trabalho analíticas em ciência de dados e inteligência de negócios. Em alguns casos, eles podem até se complementar.

Vamos ver alguns exemplos específicos abaixo:

1. Cenários de aplicação do SQLite

O SQLite é super leve, o que o torna perfeito para:

  • Armazenamento de aplicativos móveis: O SQLite é o banco de dados padrão para aplicativos Android e iOS, oferecendo armazenamento local persistente sem precisar de um servidor backend.
  • Dispositivos IoT: Os dispositivos IoT leves geralmente usam o SQLite por causa do seu tamanho pequeno e sem precisar de configuração.
  • Cache do navegador: O SQLite é normalmente usado como uma camada de cache em sistemas distribuídos ou como um armazenamento intermediário quando se transfere dados entre sistemas.

2. Aplicativos analíticos DuckDB

O DuckDB está bem conectado com fluxos de trabalho analíticos, tipo pipelines ETL. Aqui vai um exemplo de como isso pode ser feito em Python.

Usando a CLI do DuckDB:

-- Connect / create DB
ATTACH 'warehouse.duckdb' AS wh; USE wh;

-- EXTRACT: read a CSV
CREATE OR REPLACE VIEW v_orders AS
SELECT * FROM read_csv_auto('data/orders.csv');  -- order_id, customer_id, order_ts, status, amount

-- TRANSFORM: clean types + derive metrics
WITH cleaned AS (
  SELECT
    CAST(order_id AS BIGINT)              AS order_id,
    CAST(customer_id AS BIGINT)           AS customer_id,
    TRY_CAST(order_ts AS TIMESTAMP)       AS order_ts,
    COALESCE(NULLIF(status,''),'unknown') AS status,
    TRY_CAST(amount AS DOUBLE)            AS amount
  FROM v_orders
),
agg AS (
  SELECT DATE_TRUNC('day', order_ts) AS order_date,
         SUM(amount)                 AS daily_gmv,
         COUNT(*)                    AS orders
  FROM cleaned
  GROUP BY 1
)
-- LOAD: upsert curated tables + export parquet
CREATE TABLE IF NOT EXISTS fact_orders AS SELECT * FROM cleaned WHERE 1=0;
MERGE INTO fact_orders t USING cleaned s
ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET
  customer_id=s.customer_id, order_ts=s.order_ts, status=s.status, amount=s.amount
WHEN NOT MATCHED THEN INSERT VALUES
  (s.order_id, s.customer_id, s.order_ts, s.status, s.amount);

COPY agg TO 'warehouse/daily_gmv' (FORMAT PARQUET, PARTITION_BY (order_date), OVERWRITE_OR_IGNORE 1);

Agora execute o arquivo no terminal:

duckdb -c ".read etl.sql"

Como alternativa, você também pode usar o DuckDB dentro do Python para um fluxo de trabalho simplificado de análise de dados.

import duckdb, pathlib
db = pathlib.Path("warehouse.duckdb")
con = duckdb.connect(str(db))

# EXTRACT
con.execute("""
CREATE OR REPLACE VIEW v_orders AS
SELECT * FROM read_csv_auto('data/orders.csv')
""")

# TRANSFORM
con.execute("""
CREATE OR REPLACE VIEW v_clean AS
SELECT CAST(order_id AS BIGINT) order_id,
       CAST(customer_id AS BIGINT) customer_id,
       TRY_CAST(order_ts AS TIMESTAMP) order_ts,
       COALESCE(NULLIF(status,''),'unknown') status,
       TRY_CAST(amount AS DOUBLE) amount
FROM v_orders
""")

# LOAD (table + parquet export)
con.execute("CREATE TABLE IF NOT EXISTS fact_orders AS SELECT * FROM v_clean WHERE 1=0")
con.execute("""
MERGE INTO fact_orders t USING v_clean s
ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET customer_id=s.customer_id, order_ts=s.order_ts, status=s.status, amount=s.amount
WHEN NOT MATCHED THEN INSERT VALUES (s.order_id, s.customer_id, s.order_ts, s.status, s.amount)
""")
con.execute("""
COPY (SELECT DATE_TRUNC('day', order_ts) AS order_date, SUM(amount) AS daily_gmv FROM fact_orders GROUP BY 1)
TO 'warehouse/daily_gmv' (FORMAT PARQUET, PARTITION_BY (order_date), OVERWRITE_OR_IGNORE 1)
""")

3. Cenários híbridos e complementares

Analise dados SQLite no DuckDB:

O DuckDB pode consultar diretamente os dados dentro de um arquivo de banco de dados SQLite:

import duckdb

# Query a SQLite database via the sqlite_scanner extension
con = duckdb.connect()
con.install_extension("sqlite_scanner")
con.load_extension("sqlite_scanner")

result = con.execute("""
    SELECT customer_id, COUNT(*) AS orders
    FROM sqlite_scan('app_cache.db', 'orders')
    GROUP BY customer_id
    ORDER BY orders DESC
""").fetchdf()

print(result)

Otimizando o desempenho e as melhores práticas

Tanto o SQLite quanto o DuckDB são eficientes por padrão, mas o desempenho deles pode variar bastante dependendo de como os dados são inseridos, consultados e mantidos.

1. Inserções em massa e tratamento eficiente de dados

SQLite

Para grandes cargas de dados, use sempre transações. Inserir linhas uma de cada vez sem uma transação faz com que o SQLite tenha que confirmar cada linha individualmente, o que deixa o desempenho bem mais lento.

import sqlite3

conn = sqlite3.connect("perf.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS logs (id INTEGER, message TEXT)")

# Bulk insert with a single transaction
data = [(i, f"event {i}") for i in range(100000)]
cur.execute("BEGIN TRANSACTION;")
cur.executemany("INSERT INTO logs VALUES (?, ?)", data)
conn.commit()

Agrupar seus dados como no exemplo acima melhora bastante o desempenho.

DuckDB

O DuckDB lida com a ingestão de grandes conjuntos de dados de forma eficiente, especialmente a partir de arquivos externos. Use comandos COPY ou consultas diretas ao Parquet/CSV para pipelines mais rápidos.

import duckdb
con = duckdb.connect()
# Bulk load CSV into DuckDB
con.execute(""" CREATE OR REPLACE TABLE logs AS SELECT * FROM read_csv_auto('transactions.csv') """)

2. Técnicas de otimização de consultas

SQLite

Para otimizar melhor suas consultas, use índices para pesquisas.

CREATE INDEX idx_customer_id ON orders(customer_id);

Eu recomendo usar o EXPLAIN QUERY PLAN pra analisar os caminhos de execução e identificar índices que estão faltando também.

Em geral, tente manter as consultas simples e evite junções desnecessárias em ambientes com recursos limitados.

DuckDB

Para o DuckDB, você pode usar poda de colunas e empurramento de predicados.

  • Poda de coluna: O DuckDB só lê as colunas que sua consulta realmente precisa. Isso leva a menos E/S, varreduras mais rápidas — especialmente com tabelas amplas ou arquivos Parquet.
  • Empurrão de predicado: O DuckDB coloca seus filtros WHERE na varredura da tabela/arquivo para que ele possa pular grupos de linhas/páginas/arquivos que não correspondem. Isso faz com que a gente leia bem menos bytes usando as estatísticas do arquivo/partição (por exemplo, Parquet min/max).

Exemplo de poda de coluna:

-- Only reads the 'user_id' and 'amount' columns; other columns aren’t touched
SELECT user_id, SUM(amount)
FROM read_parquet('events/*.parquet')
GROUP BY user_id;

Exemplo de pushdown de predicado (Parquet):

-- Skips row groups/pages whose min/max(order_ts) are entirely outside this range
SELECT *
FROM read_parquet('events/dt=*/events.parquet')
WHERE order_ts >= TIMESTAMP '2025-09-01'
  AND order_ts <  TIMESTAMP '2025-10-01';

3. Considerações sobre manutenção e operação

  • SQLite: Operações regulares do VACUUM para recuperar espaço. Para aplicações incorporadas, certifique-se de que há E/S de disco suficiente e use o modo WAL para obter melhor durabilidade e acesso simultâneo.
  • DuckDB: Otimizado para análises; precisa de poucos ajustes. Organize grandes conjuntos de dados em arquivos Parquet particionados para aproveitar a poda de partições.Faça regularmente benchmarks de consultas em relação a cargas de trabalho de amostra para ajustar as configurações de paralelismo (via PRAGMA threads).

Desenvolvimento, integração e ecossistema

Os bancos de dados precisam estar bem integrados para garantir que os dados possam ser acessados facilmente. Agora vamos ver como cada banco de dados se integra a outros sistemas.

1. Suporte a linguagens de programação e APIs

  • SQLite: Suporte a vários idiomas. Oferece uma das mais amplas variedades de ligações de idiomas no mundo dos bancos de dados. Existem drivers oficiais e mantidos pela comunidade para Python, Java, C#, C/C++, PHP, Go, Ruby, Rust e mais de 30 outros.
  • DuckDB: Integrações robustas de ciência de dados. Foca em ligações voltadas para ciência de dados: suporte oficial para Python, R e C/C++.

2. Integração de ciência de dados e análise

DuckDB: Funciona direto com DataFrames do pandas.

Exemplo:

import duckdb 
import pandas as pd

df = pd.DataFrame({"x": [1,2,3], "y": [10,20,30]})
duckdb.query("SELECT AVG(y) FROM df").show()

O DuckDB também suporta funções definidas pelo usuário (UDFs) em SQL e Python, permitindo análises avançadas e transformações personalizadas.

Exemplo (UDF Python no DuckDB):

import duckdb
import math

con = duckdb.connect()

# Register a Python function as UDF
con.create_function("sqrt_plus", lambda x: math.sqrt(x) + 1)

result = con.execute("SELECT sqrt_plus(16)").fetchall()
print(result)  # [(5.0,)]

3. Integração de nuvem e infraestrutura

SQLite

O SQLite é um banco de dados local, feito principalmente para armazenamento local e integrado.

É usado em aplicativos nativos da nuvem como uma camada de persistência leve ou cache, geralmente dentro de contêineres. Embora não tenha conectores diretos de armazenamento em nuvem, os bancos de dados SQLite são portáteis e fáceis de transportar entre ambientes.

DuckDB

O DuckDB está tendo cada vez mais gente usando na nuvem (consultando arquivos S3 Parquet) por causa da otimização dele para arquiteturas de dados modernas.

Ele também oferece suporte nativo para consultar formatos de armazenamento em nuvem, como arquivos Parquet e Arrow no AWS S3, Azure Blob Storageou Google Nuvem Storage.

O DuckDB é ótimo pra cenários de análise sem servidor, onde os dados ficam guardados em armazenamento de objetos e são consultados quando você precisa, sem precisar de um warehouse pesado.

Limitações e Compromissos

Apesar dos pontos fortes, tanto o DuckDB quanto o SQLite têm limitações que vêm junto com a forma como foram projetados. 

  • Limitações de Concorrência e Escalabilidade:
    • SQLite: Concorrência de gravação limitada.
    • DuckDB: Modelo de concorrência de processo único.
  • Limitações de gerenciamento de memória e recursos:
    • SQLite: É leve, mas não dá pra usar com conjuntos de dados muito grandes.
    • DuckDB: Pode ser transferido para o disco, mas não foi projetado para durabilidade transacional em escala.
  • Lacunas em recursos e funcionalidades:
    • SQLite: Recursos analíticos limitados.
    • DuckDB: Robustez transacional limitada.
  • Compromissos e limitações de desempenho:
    • SQLite: Rápido para transações, lento para análises.
    • DuckDB: Rápido para análises, mais lento para pequenas gravações.

SQLite vs DuckDB Considerações finais

O DuckDB e o SQLite têm funções importantes, mas diferentes:

  • Escolha o SQLite se você precisa de um banco de dados simples, leve e transacional para aplicativos e sistemas embarcados.
  • Escolha o DuckDB se você precisa de análises de alto desempenho diretamente nos seus fluxos de trabalho Python/R.

Em muitos casos, eles se complementam: SQLite para armazenamento e transações, DuckDB para consultas analíticas sobre esses dados. A escolha certa depende se sua carga de trabalho é mais OLTP (transações) ou OLAP (análises).

Quer saber mais sobre bancos de dados como DuckDB e SQLite? Dá uma olhada no nosso tutorial Guia para Iniciantes em SQLite e nosso Introdução ao DuckDB SQL tutorial Code-Along.

Perguntas frequentes sobre DuckDB vs SQLite

Como o DuckDB lida com conjuntos de dados maiores que a memória?

O DuckDB usa um mecanismo de execução vetorizado e pode transferir resultados intermediários para o disco quando as consultas excedem a RAM disponível. Isso permite que ele processe conjuntos de dados muito maiores do que a memória, mantendo um desempenho razoável, embora a velocidade dependa muito da E/S do disco.

Quais são as principais diferenças de desempenho entre o DuckDB e o SQLite?

O SQLite é otimizado para cargas de trabalho transacionais (OLTP), sendo ótimo para pequenas inserções, atualizações e pesquisas de linha única. Já o DuckDB é feito pra lidar com cargas de trabalho analíticas (OLAP), com agregações, junções e varreduras mais rápidas em grandes conjuntos de dados, graças ao seu design em colunas e execução paralela.

O DuckDB pode ser usado para análises em tempo real?

O DuckDB é mais adequado para análises em lote ou interativas, e não para fluxos contínuos em tempo real. Ele consegue analisar dados novos rapidinho se forem inseridos ou acessados a partir de arquivos, mas não tem recursos integrados de streaming e inserção de alta frequência que a gente encontra em sistemas dedicados em tempo real.

Como o armazenamento em colunas do DuckDB melhora o desempenho das consultas?

O armazenamento em colunas permite que o DuckDB leia só as colunas necessárias para uma consulta, reduzindo a sobrecarga de E/S. Junto com a compactação e a execução vetorizada, isso melhora a eficiência do cache e acelera operações como agregações e filtros em grandes conjuntos de dados.

Quais são as limitações do uso do DuckDB para cargas de trabalho transacionais de alta simultaneidade?

O DuckDB não foi feito pra sistemas transacionais com vários usuários. Ele suporta transações ACID, mas seu modelo de concorrência é limitado, tornando-o inadequado para ambientes com muitos gravadores simultâneos ou atualizações de alta frequência. O SQLite ou um banco de dados baseado em servidor são melhores para esses cenários.


Austin Chia's photo
Author
Austin Chia
LinkedIn

Sou Austin, blogueiro e escritor de tecnologia com anos de experiência como cientista de dados e analista de dados na área de saúde. Iniciando minha jornada tecnológica com formação em biologia, agora ajudo outras pessoas a fazer a mesma transição por meio do meu blog de tecnologia. Minha paixão por tecnologia me levou a contribuir por escrito para dezenas de empresas de SaaS, inspirando outras pessoas e compartilhando minhas experiências.

Tópicos

Cursos mais populares do DataCamp

Curso

Introduction to Databases in Python

4 h
99.5K
In this course, you'll learn the basics of relational databases and how to interact with them.
Ver detalhesRight Arrow
Iniciar curso
Ver maisRight Arrow
Relacionado

blog

Uma introdução ao DuckDB: O que é e por que você deve usá-lo?

Explore o DuckDB, o banco de dados analítico rápido e fácil de usar para Python e R. Conheça seus principais recursos, casos de uso e como ele otimiza as tarefas de análise de dados.
Kurtis Pykes 's photo

Kurtis Pykes

7 min

blog

SQL Server, PostgreSQL, MySQL... qual é a diferença? Por onde devo começar?

Neste tutorial, você aprenderá algumas das diferenças básicas entre os dialetos SQL e por onde deve começar.
Mona Khalil's photo

Mona Khalil

5 min

blog

SQL vs Python: Qual você deve aprender?

Neste artigo, abordaremos os principais recursos do Python e do SQL, suas principais semelhanças e diferenças, e qual deles você deve escolher primeiro para iniciar sua jornada na ciência de dados.
Javier Canales Luna's photo

Javier Canales Luna

12 min

Tutorial

Tutorial de visão geral do banco de dados SQL

Neste tutorial, você aprenderá sobre bancos de dados em SQL.
DataCamp Team's photo

DataCamp Team

SQLAlchemy_Tutorial.

Tutorial

Tutorial de SQLAlchemy com exemplos

Aprenda a acessar e executar consultas SQL em todos os tipos de bancos de dados relacionais usando objetos Python.
Abid Ali Awan's photo

Abid Ali Awan

Tutorial

Tutorial do MySQL: Um guia abrangente para iniciantes

Descubra o que é o MySQL e como começar a usar um dos sistemas de gerenciamento de banco de dados mais populares.
Javier Canales Luna's photo

Javier Canales Luna

Ver maisVer mais