Spark도, 클러스터도, IT 부서도 없이 멀티 기가바이트 파일 때문에 컴퓨터가 멈추는 일을 막는 방법
https://product.kyobobook.co.kr/detail/S000220221456
LUVIT EPL과 유튜브 데이터로 배우는 DuckDB | 이기준 - 교보문고
LUVIT EPL과 유튜브 데이터로 배우는 DuckDB | 복잡한 데이터 분석 흐름을 더 단순하게 만드는 DuckDB 최근 주목받고 있는 DuckDB를 활용해 SQL 기반 데이터 분석과 실전 프로젝트를 학습할 수 있도록 구
product.kyobobook.co.kr
아마 겪어봤을 상황
이런 상황을 떠올려 보세요.
며칠 안에 처리해야 할 export 파일을 전달받았습니다. 4.2GB CSV 파일이고, 수백만 행의 고객 거래 데이터입니다.
요청은 한 문장입니다. "중복을 표시하고, 마스터 목록과 대조한 다음, 국가별 요약을 생성"하라는 것입니다.
그러면 여러분들은 아마도 다음과 같이 시작했을 겁니다.
import pandas as pd
df = pd.read_csv("transactions.csv")
30초. 1분. 2분. 그리고 모든 분석가가 적어도 한 번은 본 적 있는 메시지가 나타납니다.
MemoryError
16GB RAM이 있는 컴퓨터가 그날 오후까지 분석해야 했던 파일 하나를 처리하지 못하고 포기한 것입니다.
이것은 특별하지 않은 일상입니다. 청구 파일, 비즈니스 export, 품질 관리 데이터 등 모든 것이 계속해서 커지고 있지만 그 속도를 따라가지 못했습니다.
바로 이런 문제가 제가 DuckDB를 진지하게 바라보게 만든 계기였습니다.
또 하나의 유행 기술이 아니라, 매우 현실적인 문제에 대한 실용적인 답으로서 말입니다. 더 일찍 누군가가 제게 알려줬으면 좋았을 내용은 다음과 같습니다.
Pandas가 결국 한계에 부딪히는 이유
Pandas는 매일매일 사용되는 매우 훌륭한 도구입니다.
하지만 Pandas에는 결정적인 특징이 하나 있습니다. 모든 데이터를 한 번에 메모리로 불러온다는 점입니다.
4GB 파일에 대해 pd.read_csv()를 실행하면 Pandas는 “필요한 것만” 읽지 않습니다. 전체 파일을 RAM에서 압축 해제하고, 파싱하고, 구체화합니다. Python 타입과 내부 구조 때문에 원본 크기의 2~3배까지 메모리를 차지하는 경우도 많습니다. 4GB CSV 파일은 분석 코드 한 줄을 작성하기도 전에 10~12GB의 메모리를 요구할 수 있습니다.
결과는 예측 가능합니다.
- 끝없이 길어지는 로딩 시간;
- 컴퓨터를 한계까지 밀어붙이는 메모리 사용량;
- 충돌(Crash)로 인한 프로그램이 강제 종료
- 그리고 일하는 대신 도구를 기다리고 있다는 답답함.
가장 황당한 부분은 무엇일까요? 대부분의 경우 전체 파일이 필요하지 않다는 것입니다. 특정 국가의 행만 필요하거나, 40개 컬럼 중 3개만 필요하거나, 하나의 집계 결과만 필요할 때가 많습니다. Pandas는 그걸 위해 모든 것을 불러온 것입니다.
DuckDB, 2분 만에 이해하기
DuckDB는 분석용 데이터베이스입니다. 하지만 데이터베이스에 연상되는 어려운 이미지는 잠시 내려놓으세요.
설치해야 할 서버도 없습니다. 구성해야 할 클러스터도 없습니다. 도움을 요청할 관리자도 필요 없습니다. DuckDB는 일반적인 Python 라이브러리처럼 설치됩니다.
pip install duckdb
그리고 여러분의 코드 바로 옆, 여러분의 컴퓨터 안에서, 같은 프로세스 내에서 실행됩니다.
많은 사람들이 DuckDB를 "분석을 위한 SQLite"라고 부르는데, 꽤 적절한 비유입니다.
DuckDB는 매우 빠른 SQL 엔진이며, 복잡한 설정 없이 사용할 수 있고, 필터링, 집계, 대용량 데이터에 대한 조인과 같은 분석 쿼리를 위해 설계되었습니다.
처음 사용할 때 가장 인상적인 점은 CSV나 Parquet 파일을 별도의 적재 과정 없이 바로 읽을 수 있다는 것입니다.
import duckdb
duckdb.sql("""
SELECT country, COUNT(*) AS n
FROM 'transactions.csv'
GROUP BY country
""").df()
Pandas를 멈추게 만들었던 그 4GB CSV 파일을 생각해 보세요. DuckDB는 메모리를 한계까지 사용하지 않고도 몇 초 만에 국가별 집계 결과를 반환합니다.
이 차이는 단순히 조금 더 빠르다는 수준이 아닙니다.
데이터를 다루는 방식 자체를 바꿔놓습니다.
실제로 체감되는 기능들
1. 파일 전체를 메모리에 올리지 않고 읽기
이것이 핵심입니다. DuckDB는 Predicate Pushdown이라고 불리는 기법을 사용합니다. 즉, 데이터 읽는 단계에서 필터 조건을 미리 파악하여 필요한 데이터만 가져옵니다.
# €10,000 이상인 프랑스 거래만 필요할 때
duckdb.sql("""
SELECT *
FROM 'transactions.csv'
WHERE country = 'FR' AND amount > 10000
""").df()
DuckDB는 파일을 스캔하면서 필터를 즉시 적용하고, 조건에 맞는 행만 메모리에 적재합니다. Pandas가 4GB 파일 전체를 읽은 뒤 그중 2%만 사용하는 것과 달리, DuckDB는 필요한 데이터만 처리합니다.
2. 여러 파일을 한 번에 읽기
실제 업무에서는 데이터가 하나의 파일로 오지 않는 경우가 많습니다. 월별, 기관별, 국가별로 나뉘어 전달되는 경우가 흔합니다.
duckdb.sql("""
SELECT *
FROM 'exports/transactions_2025_*.csv'
""").df()
*(글롭 패턴)를 사용하면 조건에 맞는 모든 파일을 하나의 테이블처럼 읽을 수 있습니다. 더 이상 pd.concat()을 반복 호출하는 루프를 작성하면서 메모리를 낭비할 필요가 없습니다.
3. 그냥 SQL이면 된다
분석, 보고서 작성, 감사 또는 관리 업무를 해본 사람이라면 이미 SQL을 알고 있을 가능성이 높습니다.
DuckDB를 사용하면 읽기 쉽고, 재현 가능하며, 동료가 검토하기도 쉬운 쿼리를 작성할 수 있습니다.
특히 결과만큼이나 분석 과정의 추적 가능성이 중요한 프로젝트에서는 이것이 큰 장점입니다.
4. Pandas와 자연스럽게 통합된다
DuckDB는 Pandas를 대체하는 것이 아니라 보완합니다.
또한, Pandas DataFrame을 SQL 테이블처럼 직접 조회할 수 있습니다.
import pandas as pd
import duckdb
df = pd.read_excel("billing.xlsx")
# DuckDB가 Pandas DataFrame을 테이블처럼 읽음
duckdb.sql("""
SELECT client, SUM(amount) AS total
FROM df
GROUP BY client
HAVING total > 50000
""").df()
중요한 것은 Pandas와 DuckDB 중 하나를 선택하는 것이 아니라, 상황에 맞는 도구를 사용하는 것입니다.
무거운 작업은 DuckDB가, 세밀한 후처리는 Pandas가 담당합니다.
대용량 Excel 파일의 함정
솔직히 말해 기업 환경에서는 Excel 파일이 어디에서나 사용됩니다.
비즈니스 부서가 데이터를 전달할 때 사용하는 표준 형식도 Parquet가 아니라 .xlsx 파일입니다.
하지만 Excel 파일의 문제는 수십만 행만 넘어가도 다루기 어려워진다는 점입니다.
열리는 데 오래 걸리고, 수식 계산은 느려지며, 파일이 멈추는 일도 흔합니다.
Python에서도 상황은 크게 다르지 않습니다.
pd.read_excel()은 CSV를 읽는 것보다 눈에 띄게 느립니다.
하지만, DuckDB는 확장 기능을 통해 Excel 파일을 직접 읽을 수 있습니다.
import duckdb
duckdb.sql("INSTALL excel; LOAD excel;")
duckdb.sql("""
SELECT *
FROM read_xlsx('controls.xlsx', sheet = 'Data')
WHERE status = 'INCOMPLETE'
""").df()
이때 DuckDB는 중간 처리 계층 역할을 합니다. 다루기 힘든 Excel 파일을 직접 열지 않고도 SQL을 이용해 필터링하고, 집계하고, 다른 데이터와 대조할 수 있게 해줍니다.
하지만 진짜 장점은 그 다음 단계에서 나타납니다.
Excel → Parquet: 모든 데이터 분석가가 알아야 할 활용법
이 글에서 단 한 가지만 기억해야 한다면, 바로 이것입니다.
Parquet란 무엇인가?
Parquet는 분석 작업을 위해 설계된 파일 포맷입니다. CSV나 Excel이 데이터를 행(row) 단위로 저장하는 것과 달리, Parquet는 열(column) 단위로 저장합니다. 언뜻 보면 작은 차이처럼 보이지만, 실제로는 모든 것을 바꿔놓습니다.
왜 Parquet이 표준이 되었을까?
압축률
Parquet는 매우 높은 압축 효율을 제공합니다. 파일 크기가 5~10배까지 줄어들어 4GB CSV 파일이 400~800MB 수준의 Parquet 파일로 변환되는 경우가 흔합니다.
따라서, 저장 공간, 백업 용량, 파일 전송 시간 모두 크게 절약할 수 있습니다.
속도
Parquet는 데이터 타입 정보를 포함하는 구조화된 포맷입니다.
매번 텍스트를 파싱할 필요가 없고, 데이터 타입을 추론할 필요도 없습니다. 숫자는 숫자로, 날짜는 날짜로 저장됩니다.
덕분에 데이터를 읽는 속도가 훨씬 빠릅니다.
필요한 컬럼만 읽기
이것이 Parquet의 가장 큰 장점입니다.
40개 컬럼 중 3개만 필요하다면 Parquet는 해당 3개 컬럼만 디스크에서 읽어옵니다.
반면 CSV는 원하는 컬럼이 몇 개뿐이더라도 전체 파일을 끝까지 읽어야 합니다.
데이터 규모가 커질수록 성능 차이는 몇 배 수준이 아니라 수십 배 이상까지 벌어질 수 있습니다.
권장 워크플로우
Excel / CSV
↓
DuckDB
↓
Parquet
↓
Python / Power BI / Analytics
핵심 아이디어는 간단합니다.
무거운 Excel이나 CSV 파일을 한 번만 Parquet로 변환한 후, 이후의 모든 분석은 Parquet를 기준으로 수행하는 것입니다.
단 한 번의 쿼리로 변환하기
import duckdb
# CSV → Parquet
duckdb.sql("""
COPY (SELECT * FROM 'transactions.csv')
TO 'transactions.parquet' (FORMAT PARQUET)
""")
# Excel → Parquet
duckdb.sql("INSTALL excel; LOAD excel;")
duckdb.sql("""
COPY (SELECT * FROM read_xlsx('billing.xlsx'))
TO 'billing.parquet' (FORMAT PARQUET)
""")
이것만으로 충분합니다.
단 하나의 쿼리만 실행하면 다루기 힘들었던 파일이 가볍고 빠른 분석용 파일로 바뀝니다.
실제로 얻는 이점
Parquet로 변환한 후에는 쿼리 속도가 눈에 띄게 빨라집니다.
# Parquet에서는 amount 컬럼만 읽음
duckdb.sql("""
SELECT AVG(amount), MAX(amount)
FROM 'transactions.parquet'
""").df()
이 쿼리는 전체 파일을 읽지 않고 amount 컬럼만 디스크에서 가져옵니다.
Power BI에서도 효과는 매우 큽니다.
Power BI는 Parquet를 기본적으로 지원하기 때문에 데이터 새로 고침 속도가 빨라지고 데이터 모델 크기도 줄어듭니다.
매번 수백 MB짜리 CSV 파일을 불러오느라 기다리는 대신, 훨씬 가볍고 빠른 데이터 파이프라인을 구축할 수 있습니다.
이론이 아니라 실제 사례
DuckDB의 진가는 실제 업무에서 드러납니다. 다음은 비교적 규모가 큰 데이터셋이라면 어느 환경에서나 적용할 수 있는 대표적인 사례들입니다.
중복 청구서 찾기
가장 흔한 질문 중 하나입니다.
동일한 청구서가 두 번 지급된 것은 아닐까?
duckdb.sql("""
SELECT vendor, amount, invoice_date, COUNT(*) AS occurrences
FROM 'invoices.parquet'
GROUP BY vendor, amount, invoice_date
HAVING COUNT(*) > 1
ORDER BY occurrences DESC
""").df()
수백만 행의 데이터에서도 몇 초 만에 잠재적인 중복 청구 목록을 확인할 수 있습니다.
같은 작업을 Pandas로 수행할 수도 있지만, 일반적으로 더 많은 코드가 필요하고 성능과 안정성 측면에서도 불리한 경우가 많습니다.
여러 국가 데이터를 한 번에 분석하기
여러 국가나 여러 기관이 포함된 데이터에서는 국가별 규모와 이상 징후를 확인해야 하는 경우가 많습니다.
duckdb.sql("""
SELECT country,
COUNT(*) AS n_operations,
SUM(amount) AS total_volume,
AVG(amount) AS avg_amount
FROM 'operations/*.parquet'
GROUP BY country
ORDER BY total_volume DESC
""").df()
* 글롭 패턴을 사용하면 국가별 파일을 자동으로 하나의 테이블처럼 읽을 수 있습니다.
별도의 반복문도 필요 없고, 수동으로 파일을 병합할 필요도 없습니다.
기준 데이터의 완전성 점검하기
필수 항목이 누락된 레코드를 찾는 것도 매우 흔한 작업입니다.
duckdb.sql("""
SELECT
COUNT(*) AS total,
COUNT(*) FILTER (WHERE birth_date IS NULL) AS missing_birth_date,
COUNT(*) FILTER (WHERE id_document IS NULL) AS missing_id_document,
COUNT(*) FILTER (WHERE country IS NULL) AS missing_country
FROM 'master_data.parquet'
""").df()
파일을 한 번만 읽으면서 모든 품질 지표를 동시에 계산할 수 있습니다.
데이터 품질 진단 보고서나 감사 자료를 작성할 때 특히 유용합니다.
왜 이런 작업에 DuckDB가 잘 맞을까?
추적 가능성
SQL 쿼리는 읽기 쉽고 재현 가능합니다.
다른 사람이 검토할 수 있고, 동일한 결과를 다시 생성할 수도 있습니다. 분석 과정 자체를 문서화해야 하는 업무에서는 매우 중요한 장점입니다.
대용량 데이터 처리
이러한 데이터 파일은 대개 상당히 큽니다.
DuckDB는 수 GB에서 수십 GB 규모의 파일도 무리 없이 처리할 수 있습니다.
데이터 보안
모든 작업이 사용자의 로컬 컴퓨터에서 수행됩니다.
민감한 데이터를 외부 서비스나 클라우드 환경으로 전송할 필요가 없습니다.
빠른 반복 분석
실제 분석 업무는 하나의 가설을 검증하고, 결과를 확인한 뒤, 새로운 가설을 검증하는 과정을 반복합니다.
DuckDB를 사용하면 이러한 검증을 몇 초 만에 수행할 수 있기 때문에 작업 속도 자체가 달라집니다. 가설을 세우고 검증하는 과정이 훨씬 더 자연스럽고 빠르게 이루어집니다.
Spark의 가벼운 대안
이 질문에는 솔직하게 답할 필요가 있습니다. 항상 나오는 질문이기 때문입니다.
"그렇다면 Spark를 쓰면 되는 것 아닌가요?"
Spark는 분산 컴퓨팅 도구입니다. 여러 대의 서버로 구성된 클러스터에 작업을 분산하여 처리하는 것이 핵심 강점입니다. 데이터가 단일 컴퓨터에 담을 수 없을 정도로 커졌을 때, 즉 테라바이트 규모의 데이터나 대규모 분산 파이프라인을 운영할 때 Spark는 매우 중요한 역할을 합니다.
하지만 대부분의 팀이 결국 인정하게 되는 현실이 있습니다.
많은 "빅데이터" 프로젝트는 사실 빅데이터가 아닙니다.
몇 GB 규모의 데이터는 빅데이터라기보다는 단순히 큰 데이터에 가깝습니다. 그리고 적절한 도구만 사용한다면 최신 노트북에서도 충분히 처리할 수 있습니다.
DuckDB만으로 충분한 경우
- 데이터 파일이 수백 MB에서 수십 GB 수준인 경우
- 개인 또는 소규모 팀이 분석 업무를 수행하는 경우
- 인프라 구축 없이 빠르게 작업하고 싶은 경우
- 탐색적 분석(EDA), 보고서 작성, 데이터 검증, 애드혹 분석이 주 업무인 경우
이러한 상황, 즉 대부분의 데이터 분석가가 수행하는 업무에서는 DuckDB만으로도 충분합니다.
그리고 클러스터 운영이라는 복잡성을 피할 수 있습니다.
여전히 Spark가 필요한 경우
- 데이터 규모가 단일 컴퓨터의 처리 한계를 넘어서는 경우
- 장애 허용(fault tolerance)이 필요한 분산 처리가 필요한 경우
- 매우 큰 규모의 운영 환경(Production Pipeline)을 구축하는 경우
- 여러 팀이 공용 컴퓨팅 인프라를 공유하는 경우
이런 환경에서는 Spark가 여전히 적합한 선택입니다.
중요한 것은 기본값이 Spark가 아니라는 점이다
가장 좋은 접근 방식은 "일단 Spark부터 도입하자"가 아닙니다.
먼저 단순한 도구로 시작하고, 데이터 규모가 실제로 필요로 할 때만 복잡성을 추가하는 것입니다.
5GB 데이터를 처리하기 위해 Spark 클러스터를 구축하는 것은 못 하나 박기 위해 대형 해머를 꺼내는 것과 같습니다. 필요한 일은 하겠지만, 대부분의 경우 훨씬 간단한 방법이 있습니다.
DuckDB의 한계
어떤 도구도 완벽하지 않습니다. 그리고 도구를 제대로 평가하려면 장점뿐 아니라 한계도 함께 살펴봐야 합니다.
트랜잭션 데이터베이스는 아니다
DuckDB는 분석을 위해 설계되었습니다.
대규모 조회, 집계, 분석 쿼리에는 매우 강력하지만 PostgreSQL처럼 수천 명의 사용자가 동시에 데이터를 쓰고 수정하는 OLTP 환경을 목표로 만든 데이터베이스는 아닙니다.
단일 머신 기반이다
DuckDB는 하나의 컴퓨터에서 실행됩니다.
따라서 데이터 규모가 단일 머신의 CPU, 메모리, 디스크 처리 능력을 넘어서는 순간에는 적합한 선택이 아닙니다.
그런 경우에는 Spark나 클라우드 데이터 웨어하우스가 더 적절한 대안이 됩니다.
생태계가 아직 비교적 젊다
DuckDB는 매우 빠르게 성장하고 있지만 Pandas나 Spark에 비하면 생태계 규모는 아직 작습니다.
튜토리얼, 예제, 커뮤니티 자료의 양도 상대적으로 적은 편입니다.
Pandas를 완전히 대체하지는 못한다
세밀한 데이터 가공, 행 단위 처리, 시각화, 머신러닝 작업에서는 여전히 Pandas와 그 주변 생태계가 중요한 역할을 합니다.
DuckDB는 Pandas를 대체하는 도구가 아니라 함께 사용하는 도구로 보는 것이 적절합니다.
결국 DuckDB는 모든 것을 대체하는 만능 도구가 아니라, 데이터 분석가의 도구 상자를 더욱 강력하게 만들어 주는 도구입니다.
실무적인 결론
단지 원본 데이터와 분석 사이에 하나의 계층을 추가해서 Pandas를 버리지도 않고 Spark 클러스터를 구축하지도 않고도 대용량 데이터를 분석할 수 있습니다.
새로운 작업 흐름은 다음과 같습니다.
대용량 파일 도착 (CSV, Excel 등)
↓
DuckDB로 Parquet 변환
↓
SQL로 필터링·집계·검증
↓
결과를 Pandas 또는 Power BI로 전달
↓
최종 분석 및 시각화
가장 크게 달라진 점은 무엇일까요?
더 이상 도구가 작업을 방해하지 않는다는 것입니다.
예전에는 컴퓨터를 멈추게 만들던 파일들이 이제는 몇 초 만에 처리됩니다. 일정은 촉박하고 분석 과정은 추적 가능해야 하는 환경에서, 이런 차이는 매일 체감할 수 있을 정도로 큽니다.
대용량 파일을 자주 다루고 있고 Pandas가 버거워하는 모습을 자주 본다면, 오늘 오후에 직접 한 번 테스트해 보세요.
설치는 한 줄이면 끝나고, 첫 번째 쿼리는 5분 안에 실행할 수 있습니다.
이 정도로 빠르게 가치를 보여주는 도구는 생각보다 많지 않습니다.
요약
- Pandas는 데이터를 모두 메모리에 적재한 후 처리하기 때문에 대용량 파일에서는 메모리 부족이나 성능 저하가 발생할 수 있습니다. 반면 DuckDB는 쿼리에 필요한 데이터만 읽습니다.
- DuckDB는 pip install duckdb 한 줄로 설치할 수 있으며, 서버나 클러스터 없이 로컬 컴퓨터에서 실행됩니다.
- CSV, Excel, Parquet 파일을 직접 조회할 수 있으며, Pandas DataFrame도 SQL로 질의할 수 있습니다.
- 대용량 파일은 Parquet로 변환하는 것이 좋습니다. 파일 크기는 보통 5~10배 줄어들고, 읽기 속도는 빨라지며, 필요한 컬럼만 선택적으로 읽을 수 있습니다. 특히 Power BI와 함께 사용할 때 효과가 큽니다.
- 중복 데이터 탐지, 국가별 집계 분석, 데이터 완전성 점검과 같은 실무 작업을 읽기 쉽고 재현 가능한 SQL로 수행할 수 있습니다.
- 몇 GB 수준의 데이터라면 대부분 Spark가 필요하지 않습니다. Spark는 테라바이트 규모 데이터나 분산 클러스터 환경과 같은 진짜 분산 처리 작업에 사용하는 것이 적절합니다.
- DuckDB는 단일 머신 기반이며, 트랜잭션 처리용 데이터베이스가 아니고, 생태계도 아직 성장 중입니다. 따라서 모든 것을 대체하는 도구가 아니라 기존 분석 환경을 보완하는 도구로 보는 것이 적절합니다.
여러분은 이미 DuckDB를 사용해 본 적이 있나요?
만약 Excel, CSV, Parquet 파일을 다루는 업무가 많다면 어떤 용도로 활용하고 있는지 궁금합니다. 특히 기존에 시간이 오래 걸리거나 메모리 문제를 일으켰던 작업이 있었다면 DuckDB가 얼마나 도움이 되었는지도 흥미로운 이야기일 것입니다.
'EPL과 유튜브 데이터로 배우는 DuckDB' 카테고리의 다른 글
| DuckDB : 왜 모든 데이터 엔지니어가 갑자기 DuckDB를 이야기하는가? (0) | 2026.06.25 |
|---|---|
| Pandas, Polars, DuckDB로 테스트 데이터 생성하기 (0) | 2026.06.22 |
| DuckDB + Python: SQL로 CSV 파일 다루기 part 1 (0) | 2026.06.20 |
| DuckDB + Python Part 2: SQL로 Parquet 파일과 다수의 CSV 파일 다루기 (0) | 2026.06.20 |
| SQL Window Function에서 ROWS와 RANGE (0) | 2026.06.19 |
댓글