스크립트
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이는 다음 영상에서 확인하실 수 있습니다.
커뮤니티 글
아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!
이 영상에 대해 글쓰기