컬럼 기반 데이터베이스가 엄청나게 빠른 이유

BBetter Stack
컴퓨터/소프트웨어

스크립트

00:00:00포스그레스(PostgreSQL)를 정말 좋아하지만 모든 용도에 완벽하지는 않습니다. 이와는 다른 유형의
00:00:04열 기반 데이터베이스인 컬럼나 파생 데이터베이스가 있으며 특정 쿼리를 최대 40배까지 더 빠르게 실행할 수 있습니다.
00:00:10이 데이터베이스들은 행 단위가 아니라 열 단위로 데이터를 저장하므로 엄청난 이점을 얻을 수 있습니다.
00:00:15분석 플랫폼 같은 특정 사용 사례에서 말이죠. 물론 모든 기술에는 장단점이 존재하지만
00:00:20오늘날 우리는 컬럼나 데이터베이스가 정확히 무엇인지 살펴보고 몇 가지 쿼리를
00:00:25포스그레스와 비교하여 장단점을 확인해 보겠습니다. 포스그레스를 클릭하우스(ClickHouse) 및 덕디비(DuckDB)와 비교할 예정입니다.
00:00:31그러니 끝까지 시청하시면 열 기반 데이터베이스에 대한 확실한 개념을 잡으실 수 있고
00:00:36어떤 기술을 언제 선택해야 할지 알게 되실 겁니다.
00:00:43아까 영상 시작할 때 특정 쿼리를 40배 더 빠르게 실행할 수 있다고 말씀드렸는데 정말 사실입니다.
00:00:49여기에 1억 개의 행이 로드된 데이터베이스 테이블이 있습니다. 이 테이블을 대상으로 그룹 바이(GROUP BY) 쿼리를 실행해 보면
00:00:55PostgreSQL에서는 실행하는 데 약 9.7초가 걸립니다. 모든 단일 행에서 수익을 집계해야 하기 때문이죠.
00:01:00컬럼나 데이터베이스를 사용하여 정확히 동일한 데이터 세트에서 동일한 쿼리를 실행하면 어떻게 될까요?
00:01:06말 그대로 완전히 동일한 SQL을 사용합니다. 클릭하우스와 덕디비 모두 포스그레스와 유사한 SQL 문법을 지원하므로 친숙하게 느껴지실 겁니다.
00:01:13클릭하우스는 0.28초, 덕디비는 0.24초가 걸렸습니다. 무려 40배 이상 빠른 속도죠.
00:01:22이게 어떻게 가능할까요? 믿을 수 없을 만큼 놀랍지 않나요? 동일한 1억 개의 행을 단 0.24초 만에 처리하다니 말입니다.
00:01:30컬럼나 데이터베이스는 동일한 결과를 내기 위해 훨씬 적은 양의 작업만 처리하기 때문입니다.
00:01:36다른 쿼리가 작동하는 모습도 살펴봅시다. 안내 말씀 하나 드리자면, 저희는 AI와 기술 관련 콘텐츠를 꾸준히 제작하고 있으니
00:01:42이런 내용이 마음에 드신다면 베터 스택(Better Stack)을 구독해 주세요. 이번에는 두 타임스탬프 사이의 이벤트 개수를 세어볼 건데,
00:01:47국가 코드가 'gb'인 데이터만 필터링합니다. 이번 예시에서는 3월 데이터로 조회해 보겠습니다.
00:01:53결과를 보면 포스그레스는 5.9초, 클릭하우스는 0.06초, 덕디비는 0.03초가 걸렸습니다. 3월 데이터는 전체 이벤트의 약 13퍼센트를 차지하므로
00:02:02포스그레스는 여전히 수백만 개의 행을 확인해야 합니다. 여기에 적극적인 인덱스를 추가하여 성능을 개선할 수도 있겠지만
00:02:09클릭하우스와 덕디비 수준에는 미치지 못할 것입니다. 그렇다면 왜 열 저장소 방식이 이토록 훨씬 더 빠를까요?
00:02:15클릭하우스는 개별 행을 전혀 인덱싱하지 않기 때문입니다. 테이블을 생성할 때 정렬 키(Sort Key)를 지정하면
00:02:20테이블을 만들 때 정렬 키를 지정하면 데이터가 타임스탬프 순으로 정렬되고, 이를 블록 단위로 나누어
00:02:32그리고 각 블록의 첫 번째 타임스탬프 정보만 기록해 둡니다. 1억 개의 행이라면 약 12,000개의 기록이 생기는 셈이죠.
00:02:39이 정도 분량은 메모리에 충분히 올라갈 정도로 작습니다. 따라서 3월 데이터를 요청하면 이 기록들을 빠르게 검색하여
00:02:443월 데이터가 포함될 수 있는 블록을 찾아 해당 블록만 읽어옵니다. 이 경우 총 12,208개의 블록 중 1,633개만 읽고
00:02:52디스크에 있는 나머지 데이터는 전부 건너뛰게 됩니다. 덕디비도 이와 비슷한 방식을 사용합니다. 컬럼의 각 청크마다 최솟값과 최댓값을 유지하기 때문에
00:03:00특정 청크를 확인했을 때 타임스탬프가 1월부터 2월 범위라면 전체 청크를 읽지 않고 통째로 건너뛸 수 있습니다.
00:03:06여기에 필요한 컬럼만 연다는 앞서 언급한 방식까지 더해지면 0.03초라는 속도가 나오는 것입니다.
00:03:10하지만 ID로 단일 행을 조회하려고 하면 상황이 완전히 180도 뒤바뀝니다.
00:03:17이 간단한 쿼리 하나가 많은 것을 보여줍니다. 포스그레스는 2밀리초가 걸린 반면, 클릭하우스는 168밀리초가 걸렸고
00:03:26흥미롭게도 덕디비는 여전히 2밀리초를 기록했습니다. 포스그레스에는 ID에 대한 B-트리 인덱스가 있어서
00:03:32트리를 따라 내려가 해당 행이 있는 단 하나의 페이지에 바로 도달하므로 단 2밀리초 만에 끝납니다.
00:03:37하지만 클릭하우스에는 문제가 있습니다. 유일한 인덱스가 정렬 키뿐인데 이 테이블은
00:03:43타임스탬프가 1순위, ID가 2순위로 정렬되어 있습니다. 따라서 특정 ID를 요청하면 그 ID가 어느 블록에 있는지 알 수 없기 때문에
00:03:5112,208개의 블록을 전부 다 확인해야 합니다. 게다가 행을 찾았다고 해도
00:03:578개의 컬럼 파일을 모두 열어서 해당 행을 다시 조립해야 하므로 이토록 간단한 쿼리에는 엄청난 작업량이 소모됩니다.
00:04:03그렇다면 덕디비는 어떻게 이 문제를 피해 갈 수 있었을까요? 우리 데이터 덕분에 운이 좋았던 것입니다. ID들이 순서대로 삽입되었기 때문에
00:04:09각 청크의 최솟값과 최댓값이 ID와 깔끔하게 맞아떨어져서 덕디비는 올바른 청크로 곧바로 찾아갈 수 있었습니다.
00:04:16만약 ID가 무작위로 섞여 있었다면 클릭하우스처럼 전체 컬럼을 스캔해야 했을 겁니다. 이제 행을 업데이트하는
00:04:21작업을 살펴보겠습니다. 포스그레스와 덕디비용 쿼리가 하나 있고, 클릭하우스용으로는 약간 다른 버전의 쿼리가 있습니다.
00:04:26포스그레스는 5밀리초, 클릭하우스는 5.8초, 그리고 덕디비는 이번에도 수십 밀리초가 걸렸습니다.
00:04:34포스그레스는 단 하나의 행을 다시 쓰고 인덱스 항목 하나만 업데이트하면 됩니다. 반면 클릭하우스의 데이터 파일은
00:04:40불변(Immutable)이라 제자리에서 직접 수정되지 않습니다. 따라서 수익 값 하나를 변경하려면
00:04:46해당 테이블 청크의 전체 수익 컬럼 파일을 통째로 다시 써야 합니다. 클릭하우스에서는 이를 테이블 전체의 변형으로 취급하기 때문에
00:04:51반드시 'ALTER TABLE' 구문으로 작성해야 합니다. 베타 버전으로 제공되는 좀 더 가벼운 업데이트 기능이 있긴 하지만
00:04:56테이블의 약 10퍼센트 미만인 소수의 행에만 사용하도록 의도된 기능입니다. 덕디비는 이 둘의 중간쯤에 위치하는데,
00:05:03파일을 제자리에서 수정할 수 있어서 단일 행 업데이트가 수십 밀리초 내에 처리됩니다.
00:05:08마지막으로 테이블의 고유 사용자 수를 세어보겠습니다. 이번에도 클릭하우스용으로 약간 변형된 쿼리를 사용하며
00:05:14결과는 포스그레스 38.4초, 클릭하우스 0.78초, 그리고 덕디비는 1초 미만입니다.
00:05:22포스그레스는 이처럼 거대한 테이블 전체를 대상으로 집계 작업을 할 때 여전히 엄청난 양의 연산으로 인해 고생하게 됩니다.
00:05:28다양한 컬럼에 걸쳐 데이터를 집계하는 것이 일반적인 분석 같은 작업에는 보통 컬럼나 데이터베이스를 사용하고 싶으실 겁니다.
00:05:34여기서는 두 가지 옵션을 살펴보았습니다. 클릭하우스는 호스팅되는 서버 형태이며 오픈소스이고 대부분의 주요 플랫폼에서 사용할 수 있습니다.
00:05:41이를 로컬에서 실행하려면 포스그레스가 작동하는 방식과 유사하게 내 컴퓨터에 클릭하우스 서버를 띄워야 합니다.
00:05:47하지만 덕디비는 SQLite에 가깝습니다. 자체 프로세스 내부에서 실행되는 라이브러리이며 전체 데이터베이스가
00:05:54디스크 상의 단일 파일 하나로 존재합니다. 따라서 하나의 업데이트가 진행되는 동안 해당 파일이 잠길 수 있어 동시성 처리에 타격을 줍니다.
00:06:00두 데이터베이스 모두 컬럼나 데이터베이스이지만 접근 방식이 매우 다릅니다.
00:06:06결국 어떤 데이터베이스를 최종적으로 사용할 것인가는 제가 여기서 가정할 수 있는 것보다 훨씬 더 많은 요인에 의해 결정됩니다.
00:06:12로컬 기기에서 데모를 실행할 때의 단순한 쿼리 속도만이 문제가 아닙니다.
00:06:17확장성, 이중화, 그리고 기능의 확장성이 중요합니다. 물론 포스그레스에는 다양한 방식으로 기능을 확장할 수 있는 풍부한 플러그인 생태계가 있으며
00:06:24이는 다음 영상에서 확인하실 수 있습니다.

핵심 요약

컬럼나 데이터베이스는 분석 쿼리 성능을 최대 40배 이상 높이지만 단일 행 조회나 업데이트 작업에서는 행 기반 데이터베이스보다 불리할 수 있다.

하이라이트

  • 컬럼나 데이터베이스는 1억 개의 행을 대상으로 한 그룹 바이 쿼리를 0.24초 만에 처리하여 포스그레스보다 40배 이상 빠른 속도를 기록한다.

  • 클릭하우스는 개별 행을 인덱싱하지 않고 정렬 키와 블록 단위 최솟값 정보를 활용하여 디스크 데이터를 대폭 건너뛴다.

  • ID로 단일 행을 조회할 때 포스그레스는 B-트리 인덱스로 2밀리초 만에 처리하지만 정렬 키가 타임스탬프 중심인 클릭하우스는 전체 블록을 스캔한다.

  • 클릭하우스의 데이터 파일은 불변(Immutable) 성격을 가지므로 단일 행 업데이트 시 전체 컬럼 파일을 통째로 다시 써야 한다.

  • 덕디비는 프로세스 내부에서 실행되는 라이브러리 형태이며 디스크 상의 단일 파일로 존재하여 동시성 처리에 제한이 있다.

타임라인

열 기반 데이터베이스와 성능 비교

  • 컬럼나 데이터베이스는 특정 쿼리를 최대 40배까지 더 빠르게 실행한다.
  • 1억 개의 행을 가진 테이블에서 포스그레스는 그룹 바이 쿼리에 9.7초가 소요된다.
  • 동일한 쿼리에서 클릭하우스는 0.28초, 덕디비는 0.24초가 소요된다.

데이터를 행 단위가 아니라 열 단위로 저장함으로써 분석 플랫폼 같은 특정 사용 사례에서 압도적인 처리 속도를 달성한다. 클릭하우스와 덕디비 모두 포스그레스와 유사한 SQL 문법을 지원하여 동일한 쿼리를 그대로 실행할 수 있다.

열 저장소 방식의 고속 처리 원리

  • 클릭하우스는 개별 행을 전혀 인덱싱하지 않고 정렬 키와 블록 기반 정보를 사용한다.
  • 타임스탬프 조건에 부합하는 블록만 읽고 나머지 데이터는 전부 건너뛴다.
  • 덕디비는 컬럼 청크마다 최솟값과 최댓값을 유지하여 불필요한 청크 읽기를 방지한다.

전체 1억 개의 행 중 3월 데이터만 필터링하는 경우 포스그레스는 수백만 개의 행을 확인해야 하지만, 열 저장소는 전체 12,208개의 블록 중 1,633개만 읽고 디스크 데이터를 대폭 줄인다. 필요한 컬럼만 여는 방식이 결합되어 0.03초의 속도를 기록한다.

단일 행 조회 및 업데이트 성능 차이

  • ID로 단일 행을 조회할 때 포스그레스는 B-트리 인덱스를 통해 2밀리초 만에 처리한다.
  • 클릭하우스는 타임스탬프가 1순위 정렬 키이므로 전체 블록을 스캔하여 168밀리초가 소요된다.
  • 클릭하우스의 데이터 파일은 불변이므로 단일 행 업데이트 시 전체 청크 파일을 다시 써야 한다.

분석용으로 최적화된 컬럼나 데이터베이스는 단일 행 조회나 제자리 수정 작업에서 불리한 구조적 특징을 가진다. 포스그레스는 단일 행을 빠르게 다시 쓰고 인덱스 하나만 업데이트할 수 있지만 클릭하우스는 테이블 전체의 변형 작업으로 취급한다.

고유 사용자 집계와 아키텍처 특성

  • 거대한 테이블의 고유 사용자 수 집계에서 포스그레스는 38.4초가 걸린다.
  • 클릭하우스는 서버 형태로 실행되며 확장성과 이중화 기능을 제공한다.
  • 덕디비는 SQLite와 유사한 라이브러리 형태로 프로세스 내부에서 실행된다.

다양한 컬럼에 걸쳐 데이터를 집계하는 분석 작업에서는 컬럼나 데이터베이스가 압도적인 우위를 점한다. 다만 클릭하우스는 독립된 서버 형태로 운영되는 반면 덕디비는 단일 파일로 존재하여 동시성 처리에 타격을 받을 수 있으므로 사용 목적에 맞는 기술 선택이 필요하다.

커뮤니티 글

아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!

이 영상에 대해 글쓰기