DuckDB — 파일 위에서 바로 분석하는 열 지향 엔진 · 파일 위에서 바로 · 퀴즈
퀴즈: 파일 위에서 바로
문항 8개. 정답과 해설은 풀어 본 뒤에 보여 드립니다.
DuckDB 에서 `select count(*) from 'sales.csv.gz'` 가 표를 만들지 않고도 동작하는 이유는?
- 파일을 먼저 임시 표로 통째로 적재한 뒤 그 표를 질의하기 때문이다
- CSV 파일 옆에 숨은 인덱스 파일을 자동으로 만들어 두기 때문이다
- 파일 경로가 read_csv 같은 표 함수로 바뀌어 그 자리에서 읽히기 때문이다
- 운영체제가 파일을 메모리에 매핑해 두어 표처럼 보이기 때문이다
`DESCRIBE` 를 했더니 `05 Jan 2026` 이 든 날짜 열이 VARCHAR 로 나왔다. 무엇이 일어난 것인가?
- 스니퍼가 표본에서 그 형식을 날짜로 인식하지 못했다 — dateformat 을 주면 DATE 로 읽힌다
- CSV 에는 형이 없으므로 모든 열은 언제나 VARCHAR 로 들어온다
- 영문이 섞인 값은 DuckDB 가 지원하지 않는 형이라 캐스팅으로도 바꿀 수 없다
- 헤더에 공백이 있어 열 이름을 못 읽었고, 그래서 형 추론도 건너뛰었다
`nullstr = 'N/A'` 를 줬더니 이번에는 빈 칸이 있던 숫자 열이 VARCHAR 가 됐다. 왜인가?
- nullstr 는 한 열에만 적용되고 나머지 열은 원래대로 추론되기 때문이다
- nullstr 는 기본값(빈 문자열)을 대체하므로 빈 칸이 더는 NULL 로 읽히지 않는다
- N/A 가 든 열을 먼저 처리하느라 다른 열의 표본이 줄어 추론이 흔들렸다
- 숫자 열의 NULL 은 nullstr 가 아니라 types 옵션으로만 지정할 수 있다
같은 집계가 gzip CSV 에서 137ms, Parquet 에서 2ms 였다. Parquet 쪽이 빠른 가장 직접적인 이유는?
- Parquet 파일이 더 작아서 디스크에서 읽는 바이트가 그만큼 줄었기 때문이다
- Parquet 는 정렬돼 저장되므로 집계 전에 정렬 단계가 빠지기 때문이다
- Parquet 를 읽을 때는 DuckDB 가 결과를 캐시해 두 번째부터 즉시 답하기 때문이다
- 필요한 열만 이진 형식 그대로 여러 스레드가 나눠 읽고 텍스트 파싱이 없기 때문이다
gzip 으로 압축된 CSV 가 Parquet 보다 유난히 느린 데는 압축 방식 자체의 이유가 있다. 무엇인가?
- gzip 은 스트림이라 한 스레드가 처음부터 끝까지 풀어야 해서 병렬로 나눠 읽을 수 없다
- gzip 은 압축률이 낮아서 같은 데이터가 Parquet 보다 훨씬 많은 바이트를 차지한다
- gzip 파일은 확장자만 보고 읽을 수 없어 매번 압축 방식을 탐지하는 비용이 든다
- gzip 은 열 단위로 압축되어 필요한 열을 찾으려면 모든 블록을 순회해야 한다
`PARTITION_BY (month)` 로 쓴 디렉터리를 `hive_partitioning = true` 로 읽으며 `where month = '2026-03'` 을 걸면 어떻게 되나?
- 모든 파일을 열어 month 열을 읽은 뒤 조건에 맞는 행만 남긴다
- month 열이 파일 안에 없으므로 오류가 나고, 파티션 열은 조건에 쓸 수 없다
- 가장 최근 파티션 하나만 읽고 나머지는 무시하므로 조건과 무관하게 같은 결과가 나온다
- 디렉터리 이름(month=2026-03)만 보고 다른 디렉터리의 파일은 열지도 않는다
`duckdb` 를 경로 없이 열어 표를 만들고 `.quit` 했다. 다시 열면 그 표는?
- 홈 디렉터리의 기본 DB 파일에 저장되어 그대로 남아 있다
- 메모리 DB 였으므로 사라진다 — 남기려면 열 때 파일 경로를 줘야 한다
- 마지막 세션의 명령 기록에서 자동으로 다시 만들어진다
- 표 정의만 남고 데이터는 비어 있는 상태로 돌아온다
`read_csv('…/*.csv.gz', filename = true)` 에서 `filename = true` 가 하는 일은?
- 글롭에 맞는 파일 이름을 미리 검사해 스키마가 다른 파일을 걸러낸다
- 파일 이름을 표 이름으로 삼아 파일마다 별도의 표를 만든다
- 행마다 그 행이 어느 파일에서 왔는지 알려 주는 filename 열을 붙인다
- 파일 이름의 날짜 부분을 파싱해 자동으로 파티션 열을 만든다