DuckDB 분석 데이터베이스
TL;DR
- DuckDB는 서버 없이 프로세스 내부에서 동작하는 분석 전용(OLAP) 데이터베이스다.
- CSV/Parquet/JSON 같은 파일을 바로 SQL로 조회해 로컬 분석 속도를 크게 높인다.
- pandas 대비 낮은 메모리와 빠른 집계 성능으로 “분석용 SQLite” 포지션을 채운다.
1. 개념
DuckDB는 프로세스 내장형(in-process) 열 지향(컬럼 스토어) OLAP 데이터베이스로, 서버 없이 로컬 환경에서 대용량 분석 쿼리를 빠르게 수행하도록 설계됐다. CSV/Parquet/JSON 파일을 직접 SQL로 조회할 수 있어 분석 파이프라인을 단순화한다.
2. 배경
로컬 분석에서 pandas/SQLite는 느리고, Spark/BigQuery는 과도한 설정과 비용을 요구했다. DuckDB는 이 중간 지대를 메우며 노트북 한 대에서 수십 GB를 SQL로 분석할 수 있도록 등장했다. Parquet 표준화와 Python 생태계의 확산도 성장 배경이다.
3. 이유
분석 쿼리는 SELECT/GROUP BY 중심이며, 열 지향 저장과 벡터화 실행이 성능에 결정적이다. DuckDB는 서버 없이도 컬럼 스캔과 집계를 효율화해 pandas/일반 RDB 대비 빠른 분석 성능을 제공한다.
4. 특징
- 프로세스 내장형: 별도 서버 없이 라이브러리로 사용
- 열 지향 저장: 필요한 컬럼만 읽어 빠른 집계
- 파일 직접 쿼리: CSV/Parquet/JSON을 바로 SQL로 조회
- 벡터화·멀티스레드 실행: 집계/조인 성능 향상
- 단일 파일 DB: SQLite처럼 파일 기반 관리
5. 상세 내용
DuckDB 분석 데이터베이스
작성일: 2026-02-11 카테고리: Backend / 데이터베이스 / 분석 포함 내용: DuckDB, OLAP, OLTP, Columnar, 임베디드 DB, pandas 대체, Parquet, SQLite 비교
1. DuckDB란
정의
┌─────────────────────────────────────────────────────────────┐
│ │
│ DuckDB = 프로세스 내장형(in-process) 분석 전용 DB │
│ "분석용 SQLite" │
│ │
│ 핵심: │
│ ├── 서버 없음 (임베디드, 프로세스 안에서 실행) │
│ ├── 설치 = pip install duckdb (끝) │
│ ├── 열 지향(Columnar) 저장 → 분석 쿼리에 최적화 │
│ ├── CSV, Parquet, JSON 파일을 직접 SQL로 쿼리 가능 │
│ └── 단일 파일 DB (SQLite와 동일 방식) │
│ │
│ 개발: CWI (네덜란드 국립 수학 연구소) │
│ 첫 릴리즈: 2019년 │
│ │
└─────────────────────────────────────────────────────────────┘
2. 배경: 왜 나왔는가
기존의 문제
┌─────────────────────────────────────────────────────────────┐
│ │
│ 데이터 분석가의 일상: │
│ 1. CSV 파일 10GB 받음 │
│ 2. pandas로 로딩 → 메모리 부족 │
│ 3. Spark 클러스터 세팅 → 너무 과함 (설정만 반나절) │
│ 4. PostgreSQL에 import → 서버 띄우고, 테이블 만들고... │
│ 5. 결국 Excel로 열다가 포기 │
│ │
│ 갭: │
│ ├── 가벼운 것 (SQLite, pandas): 분석 쿼리 느림 │
│ ├── 강력한 것 (Spark, BigQuery): 설치/비용 과함 │
│ └── 중간이 없었음 │
│ │
│ DuckDB가 채운 공백: │
│ "노트북 한 대에서, 설치 없이, 수십 GB를 SQL로 분석" │
│ │
└─────────────────────────────────────────────────────────────┘
인기의 배경
┌─────────────────────────────────────────────────────────────┐
│ │
│ 2019년 첫 릴리즈 → 2024-2026년 폭발적 성장 │
│ │
│ 이유: │
│ ├── "Modern Data Stack"의 로컬화 트렌드 │
│ │ (BigQuery/Snowflake 비용 부담 → 로컬에서 하자) │
│ ├── Parquet 포맷의 표준화 │
│ │ (대부분 분석 데이터가 Parquet으로 저장) │
│ ├── Python 생태계와 완벽 통합 │
│ │ (pandas, Jupyter, Arrow 호환) │
│ ├── SQL을 모르는 사람은 없음 (학습 비용 0) │
│ └── 학술 연구 기반의 탄탄한 설계 (CWI) │
│ │
└─────────────────────────────────────────────────────────────┘
3. OLTP vs OLAP
┌─────────────────────────────────────────────────────────────┐
│ │
│ OLTP (트랜잭션): INSERT, UPDATE, DELETE 중심 │
│ → MySQL, PostgreSQL, SQLite │
│ → "주문 1건 저장", "회원 정보 수정" │
│ → 행(Row) 단위 접근이 빠름 │
│ │
│ OLAP (분석): SELECT, GROUP BY, JOIN, 집계 중심 │
│ → DuckDB, BigQuery, Snowflake, ClickHouse │
│ → "월별 매출 합계", "사용자별 평균 구매 금액" │
│ → 열(Column) 단위 접근이 빠름 │
│ │
└─────────────────────────────────────────────────────────────┘
행 지향 vs 열 지향
┌─────────────────────────────────────────────────────────────┐
│ │
│ 예: 1억 행 테이블에서 "age 컬럼의 평균" 구하기 │
│ │
│ 행 지향 (PostgreSQL): │
│ [이름, 나이, 주소] [이름, 나이, 주소] [이름, 나이, 주소] │
│ → 모든 행을 읽고 나이만 추출 → 느림 │
│ │
│ 열 지향 (DuckDB): │
│ [이름, 이름, 이름...] [나이, 나이, 나이...] [주소, 주소] │
│ → 나이 컬럼만 읽음 → 빠름 + 압축 효율 ↑ │
│ │
└─────────────────────────────────────────────────────────────┘
4. 사용법
Python
import duckdb
# 1. CSV를 바로 SQL로 쿼리 (import 불필요!)
result = duckdb.sql("SELECT * FROM 'sales.csv' WHERE amount > 1000")
print(result.fetchdf()) # pandas DataFrame 반환
# 2. Parquet 파일도 직접 쿼리
duckdb.sql("SELECT region, SUM(revenue) FROM 'data/*.parquet' GROUP BY region")
# 3. pandas DataFrame을 SQL로 쿼리
import pandas as pd
df = pd.DataFrame({"name": ["Kim", "Lee"], "age": [30, 25]})
duckdb.sql("SELECT * FROM df WHERE age > 27") # df를 테이블처럼 사용!
# 4. 영구 저장 (파일 DB)
con = duckdb.connect("my_data.duckdb")
con.sql("CREATE TABLE users AS SELECT * FROM 'users.csv'")
con.sql("SELECT * FROM users WHERE created_at > '2026-01-01'")
# 5. JSON도 가능
duckdb.sql("SELECT * FROM 'logs.json' WHERE level = 'ERROR'")
CLI
# CLI로 직접 사용
duckdb my_data.duckdb
# SQL 프롬프트에서 바로 쿼리
SELECT COUNT(*) FROM 'access_log.csv';
5. DuckDB가 빠른 이유
┌─────────────────────────────────────────────────────────────┐
│ │
│ pandas의 한계: │
│ ├── 전체 데이터를 메모리에 올려야 함 │
│ ├── 싱글 스레드 (기본) │
│ ├── 행 기반 처리 │
│ └── 10GB CSV → 30GB+ 메모리 필요 │
│ │
│ DuckDB의 장점: │
│ ├── 벡터화 실행 (한번에 수천 행 처리) │
│ ├── 멀티 스레드 자동 활용 │
│ ├── 열 기반 → 필요한 컬럼만 읽음 │
│ ├── 디스크 스필링 → 메모리보다 큰 데이터 처리 가능 │
│ ├── 쿼리 옵티마이저 내장 (JOIN 순서 자동 최적화 등) │
│ └── 10GB CSV → 8GB 메모리로도 처리 가능 │
│ │
│ 벤치마크 (1억 행 GROUP BY): │
│ ├── pandas: ~45초 │
│ ├── DuckDB: ~3초 │
│ └── PostgreSQL: ~12초 (서버 필요) │
│ │
└─────────────────────────────────────────────────────────────┘
6. 비교
| SQLite | DuckDB | PostgreSQL | Spark | |
|---|---|---|---|---|
| 용도 | OLTP | OLAP | OLTP+OLAP | 대규모 OLAP |
| 설치 | 없음 | 없음 | 서버 필요 | 클러스터 필요 |
| 저장 방식 | 행 지향 | 열 지향 | 행 지향 | 열 지향 |
| 분석 속도 | 느림 | 빠름 | 보통 | 빠름 |
| 데이터 크기 | ~수 GB | ~수백 GB | ~수 TB | ~수 PB |
| 동시 접속 | 제한적 | 단일 프로세스 | 수백~수천 | 수백 |
| 트랜잭션 | 지원 | 제한적 | 완전 지원 | 없음 |
| 적합한 사용 | 앱 내장 DB | 로컬 분석 | 서비스 DB | 빅데이터 |
7. 실무 활용
┌─────────────────────────────────────────────────────────────┐
│ │
│ 적합한 경우: │
│ ├── 데이터 분석가: CSV/Parquet을 SQL로 바로 분석 │
│ ├── 데이터 엔지니어: ETL 파이프라인 로컬 변환 단계 │
│ ├── 백엔드 개발자: 로그 분석, 테스트용 분석 DB │
│ └── BI/대시보드: 작은 규모에서 BigQuery 대신 사용 │
│ │
│ 안 맞는 경우: │
│ ├── 동시 접속 웹 서비스 DB → PostgreSQL │
│ ├── 실시간 INSERT 대량 → PostgreSQL, ClickHouse │
│ └── 페타바이트 규모 → Spark, BigQuery │
│ │
└─────────────────────────────────────────────────────────────┘
관련 키워드
DuckDB, OLAP, OLTP, Columnar, 열 지향, 행 지향, 임베디드 DB, in-process, pandas, Parquet, SQLite, BigQuery, Snowflake, Spark, 분석 데이터베이스, 벡터화 실행, CWI