列志向データベースが圧倒的に速い理由

BBetter Stack
Computing/Software

Transcript

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

Key Takeaway

컬럼 기반 데이터베이스는 대규모 분석 쿼리에서 40배 빠른 속도를 제공하지만, 단일 행 조회나 업데이트 작업에서는 Postgres 같은 행 기반 데이터베이스보다 성능이 떨어진다.

Highlights

  • 컬럼 기반 데이터베이스는 분석 쿼리를 Postgres보다 최대 40배 빠르게 처리한다.

  • ClickHouse는 1억 개의 행을 집계하는 그룹 바이 쿼리를 0.28초 만에 완료한다.

  • DuckDB는 1억 개의 행에 대한 동일한 집계 쿼리를 0.24초 만에 처리한다.

  • 단일 행을 ID로 조회하는 작업에서는 Postgres가 2밀리초로 가장 빠르게 완료한다.

  • ClickHouse는 불변 데이터 파일 구조 때문에 단일 행 업데이트에 5.8초가 걸린다.

  • DuckDB는 SQLite와 유사하게 디스크상의 단일 파일로 존재하며 자체 프로세스 내에서 실행된다.

Timeline

컬럼 기반 데이터베이스와 속도 비교

  • 컬럼 기반 데이터베이스는 행 대신 열을 함께 저장하여 분석 플랫폼에서 엄청난 이점을 제공한다.
  • 1억 개의 행을 대상으로 한 그룹 바이 쿼리에서 Postgres는 9.7초가 걸린다.
  • 동일한 쿼리를 실행했을 때 ClickHouse는 0.28초, DuckDB는 0.24초가 소요된다.

Postgres는 범용성이 뛰어나지만 대규모 데이터 집계 작업에서는 모든 행을 읽어야 하므로 시간이 오래 걸린다. 반면 ClickHouse와 DuckDB는 필요한 컬럼만 선택하여 읽기 때문에 40배 이상의 압도적인 속도 차이를 보여준다.

컬럼 스토어가 빠른 이유와 블록 건너뛰기

  • ClickHouse는 개별 행을 인덱싱하지 않고 정렬 키와 데이터 분할 블록을 사용한다.
  • 블록의 첫 번째 타임스탬프 기록을 통해 불필요한 디스크 읽기를 대폭 줄인다.
  • DuckDB는 컬럼 청크마다 최솟값과 최댓값을 유지하여 조건에 맞지 않는 청크를 통째로 건너 뛴다.

전체 12,208개의 블록 중 3월 데이터가 포함된 1,633개의 블록만 읽고 나머지는 전부 건너뛴다. 이와 같은 최소한의 데이터 접근 방식 덕분에 수백만 개의 행을 다루는 쿼리도 0.03초 만에 처리될 수 있다.

단일 행 선택 및 업데이트 성능 비교

  • ID로 단일 행을 선택할 때는 Postgres가 B트리 인덱스를 활용해 2밀리초 만에 처리한다.
  • ClickHouse는 단일 ID 조회 시 12,208개 블록을 전부 확인해야 하므로 168밀리초가 걸린다.
  • Postgres는 단일 행 업데이트에 5밀리초가 걸리지만 ClickHouse는 전체 컬럼 파일을 다시 작성해 5.8초가 소요된다.

분석용으로 최적화된 컬럼 기반 데이터베이스는 단일 행을 조회하거나 수정하는 트랜잭션 작업에서 심각한 약점을 드러낸다. ClickHouse는 데이터 파일이 불변이라 제자리에 수정이 불가능하며, DuckDB는 파일이 제자리에 수정될 수 있어 수십 밀리초 내에 처리된다.

사용자 수 집계와 아키텍처 차이

  • 고유 사용자 수 집계 쿼리에서 Postgres는 38.4초가 걸리지만 ClickHouse는 0.78초, DuckDB는 1초 미만이 소요된다.
  • ClickHouse는 호스팅 서버 형태의 오픈소스로 별도의 서버 프로세스로 실행된다.
  • DuckDB는 SQLite처럼 프로세스 내에서 실행되며 전체 데이터베이스가 단일 파일로 존재한다.

거대한 테이블 전체를 집계해야 하는 환경에서는 컬럼 기반 데이터베이스가 압도적인 성능을 발휘한다. 다만 ClickHouse와 DuckDB는 각각 서버 형태와 라이브러리 형태라는 근본적인 아키텍처 차이가 존재하므로 확장성과 동시성 요구사항에 따라 선택해야 한다.

Community Posts

No posts yet. Be the first to write about this video!

Write about this video