WASM: DuckDB WASM
개요
- DuckDB(임베디드 OLAP DB)를 WebAssembly로 컴파일 → 브라우저·Node.js에서 풀 SQL 분석
- Parquet / CSV / JSON / Arrow 파일을 직접 쿼리 가능 (HTTP Range 요청으로 부분 다운로드)
- 컬럼 기반·벡터화 실행으로 수백 MB ~ 수 GB 데이터셋도 클라이언트 분석 가능
- 공식 문서 / npm
특징
- OLAP 특화: 컬럼형 저장, 벡터화 실행, 병렬 처리
- 포맷 직접 쿼리:
SELECT * FROM 'data.parquet'— 변환·import 불필요 - HTTP 원격 파일: Parquet의 footer/메타데이터만 받아 부분 스캔 (Range 요청)
- 번들 옵션: 환경별로 MVP / EH(예외 처리) / EH+threads 번들 자동 선택
- Web Worker: 무거운 쿼리도 메인 스레드 차단 없이 실행
- 영속 저장: OPFS 지원 (
opfs://또는PRAGMA enable_external_access)
설치 및 초기화
-
설치
npm install @duckdb/duckdb-wasm -
초기화 (Vite / Webpack)
import * as duckdb from '@duckdb/duckdb-wasm'; const bundles = duckdb.getJsDelivrBundles(); const bundle = await duckdb.selectBundle(bundles); const worker = new Worker(bundle.mainWorker); const logger = new duckdb.ConsoleLogger(); const db = new duckdb.AsyncDuckDB(logger, worker); await db.instantiate(bundle.mainModule, bundle.pthreadWorker); const conn = await db.connect();
기본 쿼리
const result = await conn.query(`SELECT 42 AS answer`);
console.log(result.toArray()); // Apache Arrow Table
Parquet / CSV 직접 쿼리
-
원격 Parquet (HTTP Range)
await conn.query(` SELECT count(*) FROM 'https://example.com/yellow_tripdata_2023-01.parquet' WHERE passenger_count > 2 `); -
로컬 파일 등록
await db.registerFileBuffer('data.csv', new Uint8Array(buffer)); await conn.query(`SELECT * FROM read_csv_auto('data.csv') LIMIT 10`);
Arrow 통합
- 결과가 Apache Arrow 포맷 → 시각화 라이브러리(Observable Plot, Vega, Perspective)에 0-copy 전달
- JavaScript ↔ DuckDB 간 직렬화 비용 최소화
OPFS 영속 저장
const db = new duckdb.AsyncDuckDB(logger, worker);
await db.instantiate(bundle.mainModule, bundle.pthreadWorker);
await db.open({ path: 'opfs://my.db', accessMode: duckdb.DuckDBAccessMode.READ_WRITE });
활용 사례
- 브라우저 내 BI / 데이터 탐색 도구 (Mosaic, Evidence, Observable 등)
- 데이터 카탈로그·미리보기 (대용량 Parquet 미리 보기)
- 클라이언트사이드 ETL / 변환
- 노트북·문서 안에서의 대화형 데이터 분석
- 서버 부하 없이 사용자 디바이스에서 대시보드 실행
SQLite WASM과의 비교
| 항목 | SQLite WASM | DuckDB WASM |
|---|---|---|
| 워크로드 | OLTP (트랜잭션·CRUD) | OLAP (집계·분석) |
| 저장 모델 | 행 기반 | 컬럼 기반 |
| 데이터 크기 | 수백 MB까지 적합 | 수 GB 데이터셋도 분석 가능 |
| 외부 포맷 | 직접 쿼리 제한 | Parquet/CSV/JSON 직접 쿼리 |
| 실행 | 단일 스레드 중심 | 벡터화·병렬 실행 |
| 동기 OPFS | OPFS SAH (동기) 강력 | 비동기 중심 |
- 두 엔진은 상호 보완 — 트랜잭션 저장은 SQLite, 분석은 DuckDB
한계
- 번들 크기 약 6~10MB (DuckDB 코어가 큼) → 초기 로딩 비용
- 모든 DuckDB 확장(extension)이 WASM에서 지원되지는 않음
- 멀티스레딩(EH+threads)은 COOP/COEP 헤더 필요
- 메모리 한계는 브라우저 탭 메모리에 좌우