개요

DuckDB는 OLAP(Online Analytical Processing)에 최적화된 인메모리 분석 데이터베이스입니다. SQLite가 OLTP의 임베디드 DB라면, DuckDB는 OLAP의 임베디드 DB를 목표로 합니다. 서버 설치 없이 프로세스 내에서 실행되며, Parquet, CSV, JSON 파일을 직접 쿼리할 수 있어 데이터 분석 워크플로를 혁신적으로 단순화합니다.

핵심 개념

컬럼 지향 저장: DuckDB는 데이터를 행이 아닌 열 단위로 저장합니다. 분석 쿼리에서 특정 컬럼만 읽어야 할 때 불필요한 I/O를 제거하여, 집계 연산에서 행 기반 DB 대비 10~100배 빠른 성능을 보여줍니다.

벡터화된 실행 엔진: 한 번에 하나의 행을 처리하는 Volcano 모델 대신, 벡터(배치) 단위로 처리합니다. CPU 캐시 효율과 SIMD 활용도가 높아 최신 하드웨어에서 최적의 성능을 발휘합니다.

제로 의존성: C++로 작성된 단일 바이너리로, 외부 의존성이 없습니다. Python, Node.js, R, Java 등 다양한 언어에서 라이브러리로 임포트하여 즉시 사용할 수 있습니다.

직접 파일 쿼리: Parquet, CSV, JSON, Excel 파일을 테이블로 로드하지 않고 직접 SQL로 쿼리할 수 있습니다. S3, GCS의 원격 파일도 직접 접근 가능합니다.

실전 예제

DuckDB의 강력한 분석 쿼리 기능을 살펴봅니다.

-- Parquet 파일 직접 쿼리 (로컬 또는 S3)
SELECT
  date_trunc('month', order_date) AS month,
  category,
  SUM(amount) AS total_sales,
  COUNT(*) AS order_count
FROM read_parquet('s3://my-bucket/orders/*.parquet')
WHERE order_date >= '2024-01-01'
GROUP BY ALL
ORDER BY month, total_sales DESC;

-- CSV 파일 조인
SELECT
  c.name,
  SUM(o.amount) AS lifetime_value,
  COUNT(o.id) AS total_orders
FROM read_csv('customers.csv', auto_detect=true) AS c
JOIN read_parquet('orders.parquet') AS o
  ON c.id = o.customer_id
GROUP BY c.name
HAVING lifetime_value > 1000000
ORDER BY lifetime_value DESC
LIMIT 20;

-- PIVOT 쿼리 (DuckDB 네이티브 지원)
PIVOT monthly_sales
ON month
USING SUM(revenue)
GROUP BY product_category;

-- 윈도우 함수 활용 분석
SELECT
  product_name,
  sales_date,
  daily_sales,
  AVG(daily_sales) OVER (
    PARTITION BY product_name
    ORDER BY sales_date
    ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
  ) AS moving_avg_7d
FROM daily_product_sales;

Python에서 Pandas와 함께 활용하는 예제입니다.

import duckdb
import pandas as pd

# Pandas DataFrame을 직접 SQL로 쿼리
df = pd.read_csv('large_dataset.csv')

result = duckdb.sql("""
    SELECT category,
           AVG(price) as avg_price,
           PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY price) as median
    FROM df
    GROUP BY category
    ORDER BY avg_price DESC
""").df()

# 여러 파일 포맷 간 변환
duckdb.sql("""
    COPY (SELECT * FROM read_csv('input.csv'))
    TO 'output.parquet' (FORMAT PARQUET, COMPRESSION ZSTD)
""")

활용 팁

  • 대용량 CSV 분석: 수 GB의 CSV 파일을 Pandas로 로드하면 메모리 부족이 발생하지만, DuckDB는 디스크 스필링을 지원하여 메모리보다 큰 데이터도 처리할 수 있습니다.
  • ETL 파이프라인: CSV에서 Parquet로의 변환, 데이터 정제, 집계 등을 SQL 한 줄로 처리할 수 있어 ETL 스크립트가 크게 단순해집니다.
  • Jupyter 통합: DuckDB의 Jupyter 매직 명령어(%%sql)를 사용하면 노트북에서 SQL 쿼리를 직접 실행하고 결과를 시각화할 수 있습니다.
  • PostgreSQL 연동: postgres_scanner 확장으로 PostgreSQL 테이블을 직접 쿼리할 수 있어, OLTP DB의 데이터를 별도 ETL 없이 분석할 수 있습니다.
  • WASM 지원: DuckDB-WASM을 사용하면 브라우저에서 직접 SQL 분석이 가능합니다. 클라이언트 사이드 분석 대시보드 구축에 활용할 수 있습니다.

마무리

DuckDB는 데이터 분석 워크플로를 근본적으로 바꾸고 있습니다. 서버 설치, 데이터 로드, ETL 파이프라인 없이 파일에 직접 SQL을 실행할 수 있다는 것은 데이터 분석가와 엔지니어 모두에게 엄청난 생산성 향상을 가져옵니다. 특히 Python 생태계와의 원활한 통합으로, Pandas를 대체하는 분석 도구로 빠르게 자리잡고 있습니다.