메인 콘텐츠로 건너뛰기

리소스 구성

ClickHouse Cloud의 리소스 구성 방식은 BigQuery의 리소스 계층 구조와 유사합니다. 아래에서는 ClickHouse Cloud 리소스 계층 구조를 보여주는 다음 다이어그램을 바탕으로 구체적인 차이점을 설명합니다.

조직

BigQuery와 마찬가지로 조직은 ClickHouse Cloud 리소스 계층 구조의 최상위 노드입니다. ClickHouse Cloud 계정에서 처음 생성한 사용자는 자동으로 해당 사용자가 소유한 조직에 배정됩니다. 사용자는 해당 조직에 다른 사용자를 초대할 수 있습니다.

BigQuery 프로젝트와 ClickHouse Cloud 서비스 비교

조직 내에서는 서비스를 생성할 수 있으며, ClickHouse Cloud에 저장된 데이터는 서비스에 귀속되므로 BigQuery 프로젝트와 대체로 비슷한 개념으로 볼 수 있습니다. ClickHouse Cloud에서는 여러 서비스 유형을 사용할 수 있습니다. 각 ClickHouse Cloud 서비스는 특정 리전에 배포되며 다음을 포함합니다:
  1. 컴퓨트 노드 그룹(현재 개발 tier 서비스는 2개의 노드, 프로덕션 tier 서비스는 3개의 노드)입니다. 이러한 노드에 대해 ClickHouse Cloud는 수동 및 자동 방식 모두에서 수직 및 수평 스케일링을 지원합니다.
  2. 서비스의 모든 데이터를 저장하는 객체 스토리지 폴더.
  3. endpoint(또는 ClickHouse Cloud UI Console을 통해 생성된 여러 endpoint) - 서비스에 연결할 때 사용하는 서비스 URL(예: https://dv2fzne24g.us-east-1.aws.clickhouse.cloud:8443)

BigQuery 데이터셋 vs ClickHouse Cloud 데이터베이스

ClickHouse는 테이블을 논리적으로 데이터베이스로 묶습니다. BigQuery 데이터셋과 마찬가지로 ClickHouse 데이터베이스는 테이블 데이터를 구성하고 이에 대한 접근을 제어하는 논리적 컨테이너입니다.

BigQuery 폴더

ClickHouse Cloud에는 현재 BigQuery의 폴더에 해당하는 개념이 없습니다.

BigQuery 슬롯 예약 및 쿼터

BigQuery 슬롯 예약과 마찬가지로 ClickHouse Cloud에서는 수직 및 수평 자동 스케일링을 구성할 수 있습니다. 수직 자동 스케일링의 경우 서비스의 컴퓨트 노드에 대해 메모리와 CPU 코어의 최소 및 최대 크기를 설정할 수 있습니다. 그러면 서비스는 해당 범위 내에서 필요에 따라 스케일링됩니다. 이러한 설정은 초기 서비스 생성 과정에서도 지정할 수 있습니다. 서비스의 각 컴퓨트 노드는 모두 동일한 크기를 가집니다. 수평 스케일링을 통해 서비스 내 컴퓨트 노드 수를 변경할 수 있습니다. 또한 BigQuery 쿼터와 유사하게 ClickHouse Cloud는 동시성 제어, 메모리 사용량 제한, I/O 스케줄링을 제공하므로 쿼리를 워크로드 클래스로 격리할 수 있습니다. 특정 워크로드 클래스에 대해 공유 리소스(CPU 코어, DRAM, 디스크 및 네트워크 I/O)의 제한을 설정하면 해당 쿼리가 다른 중요한 비즈니스 쿼리에 영향을 주지 않도록 할 수 있습니다. 동시성 제어는 동시 쿼리 수가 많은 상황에서 스레드 과구독을 방지합니다. ClickHouse는 서버, 사용자, 쿼리 수준에서 메모리 할당의 바이트 크기를 추적하므로 메모리 사용량 제한을 유연하게 적용할 수 있습니다. 메모리 오버커밋은 다른 쿼리의 메모리 제한을 보장하면서도 쿼리가 보장된 메모리를 초과하는 추가 여유 메모리를 사용할 수 있게 합니다. 또한 집계, 정렬, join 절의 메모리 사용량도 제한할 수 있으므로 메모리 한도를 초과할 경우 외부 알고리즘으로 폴백할 수 있습니다. 마지막으로 I/O 스케줄링을 사용하면 최대 대역폭, 진행 중인 요청 수, 정책을 기준으로 워크로드 클래스의 로컬 및 원격 디스크 접근을 제한할 수 있습니다.

권한

ClickHouse Cloud는 Cloud Console데이터베이스(database), 이렇게 두 곳에서 사용자 액세스를 제어합니다. Console 액세스는 clickhouse.cloud 사용자 인터페이스를 통해 관리됩니다. 데이터베이스 액세스는 데이터베이스 사용자 계정과 역할을 통해 관리됩니다. 또한 Console 사용자는 SQL 콘솔을 통해 데이터베이스를 사용할 수 있도록 데이터베이스 내 역할을 부여받을 수 있습니다.

데이터 타입

ClickHouse는 수치형 타입에서 더 세분화된 정밀도를 제공합니다. 예를 들어 BigQuery는 INT64, NUMERIC, BIGNUMERIC, FLOAT64 수치형 타입을 제공합니다. 반면 ClickHouse는 Decimal, Float, Integer에 대해 다양한 정밀도의 타입을 제공합니다. 이러한 데이터 타입을 사용하면 스토리지와 메모리 오버헤드를 최적화할 수 있으므로 쿼리 성능이 향상되고 리소스 활용량도 줄어듭니다. 아래에서는 각 BigQuery 타입에 해당하는 ClickHouse 타입을 매핑합니다. ClickHouse 타입에 여러 옵션이 제시되는 경우 실제 데이터 범위를 고려해 필요한 최소 타입을 선택하십시오. 또한 추가 압축을 위해 적절한 코덱 사용도 고려하십시오.

쿼리 가속 기법

프라이머리 키, 외래 키 및 프라이머리 인덱스

BigQuery에서는 테이블에 프라이머리 키 및 외래 키 제약 조건을 정의할 수 있습니다. 일반적으로 프라이머리 키와 외래 키는 관계형 데이터베이스에서 데이터 무결성을 보장하는 데 사용됩니다. 프라이머리 키 값은 보통 각 행마다 고유하며 NULL이 아닙니다. 각 행의 외래 키 값은 프라이머리 키 테이블의 프라이머리 키 컬럼에 존재하거나 NULL이어야 합니다. BigQuery에서는 이러한 제약 조건이 강제되지는 않지만, 쿼리 최적화기가 이 정보를 활용해 쿼리를 더 효율적으로 최적화할 수 있습니다. ClickHouse에서도 테이블에 프라이머리 키를 둘 수 있습니다. BigQuery와 마찬가지로 ClickHouse도 테이블의 프라이머리 키 컬럼 값에 대한 고유성을 강제하지는 않습니다. BigQuery와 달리, 테이블 데이터는 프라이머리 키 컬럼을 기준으로 정렬된 순서대로 디스크에 저장됩니다. 쿼리 최적화기는 이 정렬 순서를 활용해 재정렬을 방지하고, 조인 시 메모리 사용량을 최소화하며, LIMIT 절에서 조기 종료를 가능하게 합니다. 또한 BigQuery와 달리 ClickHouse는 프라이머리 키 컬럼 값을 기반으로 (희소) 프라이머리 인덱스를 자동으로 생성합니다. 이 인덱스는 프라이머리 키 컬럼에 대한 필터가 포함된 모든 쿼리의 속도를 높이는 데 사용됩니다. 현재 ClickHouse는 외래 키 제약 조건을 지원하지 않습니다.

보조 인덱스 (ClickHouse에서만 사용 가능)

테이블의 프라이머리 키 컬럼 값으로 생성되는 프라이머리 인덱스 외에도, ClickHouse에서는 프라이머리 키에 포함되지 않은 다른 컬럼에 보조 인덱스를 생성할 수 있습니다. ClickHouse는 여러 종류의 보조 인덱스를 제공하며, 각 인덱스는 서로 다른 유형의 쿼리에 적합합니다:
  • 블룸 필터 인덱스:
    • 동등 조건(예: =, IN)이 있는 쿼리의 속도를 높이는 데 사용됩니다.
    • 확률적 자료구조를 사용해 값이 데이터 블록에 존재하는지 판단합니다.
  • 토큰 블룸 필터 인덱스:
    • 블룸 필터 인덱스와 유사하지만 토큰화된 문자열에 사용되며, 전문 검색 쿼리에 적합합니다.
  • Min-Max 인덱스:
    • 각 데이터 파트별로 컬럼의 최솟값과 최댓값을 유지합니다.
    • 지정된 범위에 속하지 않는 데이터 파트를 읽지 않고 건너뛸 수 있도록 도와줍니다.

검색 인덱스

BigQuery의 검색 인덱스와 마찬가지로, 문자열 값을 포함하는 컬럼에 대해 ClickHouse 테이블에 전문 검색 인덱스를 생성할 수 있습니다.

벡터 인덱스

BigQuery는 최근 벡터 인덱스를 Pre-GA 기능으로 도입했습니다. ClickHouse 역시 벡터 검색 사용 사례의 성능을 높이기 위한 인덱스를 실험적으로 지원합니다.

파티셔닝

BigQuery와 마찬가지로 ClickHouse는 대규모 테이블을 파티션이라고 하는 더 작고 관리하기 쉬운 단위로 나누는 테이블 파티셔닝을 사용하여 성능과 관리 편의성을 높입니다. ClickHouse 파티셔닝에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

클러스터링

클러스터링을 사용하면 BigQuery는 지정된 몇 개의 컬럼 값을 기준으로 테이블 데이터를 자동으로 정렬하고, 최적의 크기로 구성된 블록에 함께 저장합니다. 클러스터링은 쿼리 성능을 향상시키고, BigQuery가 쿼리 실행 비용을 더 정확하게 추정할 수 있게 해줍니다. 또한 클러스터링된 컬럼을 사용하면 불필요한 데이터 스캔도 줄일 수 있습니다. ClickHouse에서는 테이블의 프라이머리 키(primary key) 컬럼을 기준으로 데이터가 디스크에 자동으로 클러스터링되며, 프라이머리 인덱스 데이터 구조를 활용하는 쿼리가 빠르게 찾거나 제외할 수 있는 블록으로 논리적으로 구성됩니다.

materialized views

BigQuery와 ClickHouse는 모두 materialized view를 지원합니다. materialized view는 성능과 효율성을 높이기 위해 기본 테이블(base table)에 대한 변환 쿼리 결과를 기반으로 미리 계산된 결과를 저장합니다.

materialized view 쿼리

BigQuery의 materialized view는 직접 쿼리할 수도 있고, 옵티마이저가 기본 테이블(base table)에 대한 쿼리를 처리하는 데 사용할 수도 있습니다. 기본 테이블의 변경으로 materialized view가 무효화될 수 있으면 데이터는 기본 테이블에서 직접 읽습니다. 반대로 기본 테이블의 변경이 materialized view를 무효화하지 않으면, 나머지 데이터는 materialized view에서 읽고 변경된 부분만 기본 테이블에서 읽습니다. ClickHouse에서는 materialized view를 직접 쿼리하는 방식만 지원합니다. 그러나 BigQuery에서는 materialized view가 기본 테이블 변경 후 5분 이내에 자동으로 갱신되지만 30분마다보다 더 자주 갱신되지는 않는 것과 달리, ClickHouse의 materialized view는 항상 기본 테이블과 동기화되어 있습니다. materialized view 업데이트 BigQuery는 주기적으로 뷰의 변환 쿼리를 기본 테이블에 대해 실행해 materialized view를 전체 갱신합니다. 갱신 사이에는 BigQuery가 materialized view의 데이터와 기본 테이블의 새 데이터를 결합해, materialized view를 계속 활용하면서도 일관된 쿼리 결과를 제공합니다. ClickHouse에서 materialized view는 증분 방식으로 업데이트됩니다. 이러한 증분 업데이트 메커니즘은 높은 확장성과 낮은 컴퓨팅 비용을 제공합니다. 증분 업데이트되는 materialized view는 기본 테이블에 수십억 또는 수조 개의 행이 포함된 시나리오에 특히 적합하도록 설계되었습니다. 계속 커지는 기본 테이블을 반복해서 쿼리해 materialized view를 갱신하는 대신, ClickHouse는 새로 삽입된 기본 테이블 행의 값만으로 부분 결과를 계산합니다. 이 부분 결과는 이전에 계산된 부분 결과와 백그라운드에서 점진적으로 머지됩니다. 그 결과, 전체 기본 테이블을 반복해서 기준으로 materialized view를 갱신하는 방식에 비해 컴퓨팅 비용이 크게 낮아집니다.

트랜잭션

ClickHouse와 달리 BigQuery는 단일 쿼리 내에서, 또는 세션을 사용할 경우 여러 쿼리에 걸쳐 다중 문 트랜잭션을 지원합니다. 다중 문 트랜잭션을 사용하면 하나 이상의 테이블에서 행을 삽입하거나 삭제하는 등의 데이터 변경 작업을 수행한 뒤, 변경 사항을 원자적으로 커밋하거나 롤백할 수 있습니다. 다중 문 트랜잭션은 ClickHouse의 2024년 로드맵에 포함되어 있습니다.

집계 함수

BigQuery와 비교하면 ClickHouse는 기본 제공 집계 함수가 훨씬 더 많습니다.

데이터 소스와 파일 포맷

BigQuery와 비교했을 때 ClickHouse는 훨씬 더 다양한 파일 포맷과 데이터 소스를 지원합니다.
  • ClickHouse는 사실상 모든 데이터 소스에서 90개 이상의 파일 포맷으로 데이터를 로드할 수 있도록 네이티브로 지원합니다
  • BigQuery는 5개의 파일 포맷과 19개의 데이터 소스를 지원합니다

SQL 언어 기능

ClickHouse는 분석 작업에 더 적합하도록 다양한 확장과 개선을 더한 표준 SQL을 제공합니다. 예를 들어, ClickHouse SQL은 람다 함수와 고차 함수를 지원하므로, 변환을 적용할 때 배열을 unnest/explode하지 않아도 됩니다. 이는 BigQuery와 같은 다른 시스템에 비해 큰 장점입니다.

배열

BigQuery에 배열 함수가 8개 있는 것과 비교하면, ClickHouse는 다양한 문제를 우아하고 간단하게 모델링하고 해결할 수 있도록 80개가 넘는 내장 배열 함수를 제공합니다. ClickHouse의 대표적인 설계 패턴은 groupArray 집계 함수를 사용해 테이블의 특정 행 값을 (일시적으로) 배열로 변환하는 것입니다. 그런 다음 배열 함수를 사용해 이를 편리하게 처리할 수 있고, 결과는 arrayJoin 함수를 통해 다시 테이블의 개별 행으로 변환할 수 있습니다. ClickHouse SQL은 고차 람다 함수를 지원하므로, BigQuery에서 배열 필터링이나 배열 zipping처럼 흔히 필요한 배열을 다시 테이블로 일시 변환하는 과정 없이도, 고차 내장 배열 함수 하나만 호출하여 다양한 고급 배열 연산을 수행할 수 있습니다. ClickHouse에서는 이러한 연산을 각각 고차 함수 arrayFilterarrayZip를 호출하는 것만으로 간단히 처리할 수 있습니다. 아래에서는 BigQuery의 배열 연산을 ClickHouse에 대응해 정리했습니다: 하위 쿼리의 각 행에 대해 요소 하나씩 포함하는 배열 만들기 BigQuery ARRAY 함수
SELECT ARRAY
  (SELECT 1 UNION  ALL
   SELECT 2 UNION ALL
   SELECT 3) AS new_array;

/*-----------*
 | new_array |
 +-----------+
 | [1, 2, 3] |
 *-----------*/
ClickHouse groupArray 집계 함수
SELECT groupArray(*) AS new_array
FROM
(
    SELECT 1
    UNION ALL
    SELECT 2
    UNION ALL
    SELECT 3
)
   ┌─new_array─┐
1. │ [1,2,3]   │
   └───────────┘
배열을 여러 행으로 변환 BigQuery UNNEST 연산자
SELECT *
FROM UNNEST(['foo', 'bar', 'baz', 'qux', 'corge', 'garply', 'waldo', 'fred'])
  AS element
WITH OFFSET AS offset
ORDER BY offset;

/*----------+--------*
 | element  | offset |
 +----------+--------+
 | foo      | 0      |
 | bar      | 1      |
 | baz      | 2      |
 | qux      | 3      |
 | corge    | 4      |
 | garply   | 5      |
 | waldo    | 6      |
 | fred     | 7      |
 *----------+--------*/
ClickHouse ARRAY JOIN
WITH ['foo', 'bar', 'baz', 'qux', 'corge', 'garply', 'waldo', 'fred'] AS values
SELECT element, num-1 AS offset
FROM (SELECT values AS element) AS subquery
ARRAY JOIN element, arrayEnumerate(element) AS num;

/*----------+--------*
 | element  | offset |
 +----------+--------+
 | foo      | 0      |
 | bar      | 1      |
 | baz      | 2      |
 | qux      | 3      |
 | corge    | 4      |
 | garply   | 5      |
 | waldo    | 6      |
 | fred     | 7      |
 *----------+--------*/
날짜 배열 반환 BigQuery GENERATE_DATE_ARRAY 함수
SELECT GENERATE_DATE_ARRAY('2016-10-05', '2016-10-08') AS example;

/*--------------------------------------------------*
 | example                                          |
 +--------------------------------------------------+
 | [2016-10-05, 2016-10-06, 2016-10-07, 2016-10-08] |
 *--------------------------------------------------*/
range + arrayMap 함수 ClickHouse
SELECT arrayMap(x -> (toDate('2016-10-05') + x), range(toUInt32((toDate('2016-10-08') - toDate('2016-10-05')) + 1))) AS example
┌─example───────────────────────────────────────────────┐
1. │ ['2016-10-05','2016-10-06','2016-10-07','2016-10-08'] │
   └───────────────────────────────────────────────────────┘
타임스탬프 배열 반환 BigQuery GENERATE_TIMESTAMP_ARRAY 함수
SELECT GENERATE_TIMESTAMP_ARRAY('2016-10-05 00:00:00', '2016-10-07 00:00:00',
                                INTERVAL 1 DAY) AS timestamp_array;

/*--------------------------------------------------------------------------*
 | timestamp_array                                                          |
 +--------------------------------------------------------------------------+
 | [2016-10-05 00:00:00+00, 2016-10-06 00:00:00+00, 2016-10-07 00:00:00+00] |
 *--------------------------------------------------------------------------*/
ClickHouse range + arrayMap 함수
SELECT arrayMap(x -> (toDateTime('2016-10-05 00:00:00') + toIntervalDay(x)), range(dateDiff('day', toDateTime('2016-10-05 00:00:00'), toDateTime('2016-10-07 00:00:00')) + 1)) AS timestamp_array
Query id: b324c11f-655b-479f-9337-f4d34fd02190

   ┌─timestamp_array─────────────────────────────────────────────────────┐
1. │ ['2016-10-05 00:00:00','2016-10-06 00:00:00','2016-10-07 00:00:00'] │
   └─────────────────────────────────────────────────────────────────────┘
배열 필터링 BigQuery UNNEST 연산자를 통해 배열을 다시 테이블로 변환하는 과정이 임시로 필요합니다.
WITH Sequences AS
  (SELECT [0, 1, 1, 2, 3, 5] AS some_numbers
   UNION ALL SELECT [2, 4, 8, 16, 32] AS some_numbers
   UNION ALL SELECT [5, 10] AS some_numbers)
SELECT
  ARRAY(SELECT x * 2
        FROM UNNEST(some_numbers) AS x
        WHERE x < 5) AS doubled_less_than_five
FROM Sequences;

/*------------------------*
 | doubled_less_than_five |
 +------------------------+
 | [0, 2, 2, 4, 6]        |
 | [4, 8]                 |
 | []                     |
 *------------------------*/
ClickHouse arrayFilter 함수
WITH Sequences AS
    (
        SELECT [0, 1, 1, 2, 3, 5] AS some_numbers
        UNION ALL
        SELECT [2, 4, 8, 16, 32] AS some_numbers
        UNION ALL
        SELECT [5, 10] AS some_numbers
    )
SELECT arrayMap(x -> (x * 2), arrayFilter(x -> (x < 5), some_numbers)) AS doubled_less_than_five
FROM Sequences;
   ┌─doubled_less_than_five─┐
1. │ [0,2,2,4,6]            │
   └────────────────────────┘
   ┌─doubled_less_than_five─┐
2. │ []                     │
   └────────────────────────┘
   ┌─doubled_less_than_five─┐
3. │ [4,8]                  │
   └────────────────────────┘
배열 결합 BigQuery UNNEST 연산자를 사용해 배열을 일시적으로 다시 테이블로 변환해야 합니다
WITH
  Combinations AS (
    SELECT
      ['a', 'b'] AS letters,
      [1, 2, 3] AS numbers
  )
SELECT
  ARRAY(
    SELECT AS STRUCT
      letters[SAFE_OFFSET(index)] AS letter,
      numbers[SAFE_OFFSET(index)] AS number
    FROM Combinations
    CROSS JOIN
      UNNEST(
        GENERATE_ARRAY(
          0,
          LEAST(ARRAY_LENGTH(letters), ARRAY_LENGTH(numbers)) - 1)) AS index
    ORDER BY index
  );

/*------------------------------*
 | pairs                        |
 +------------------------------+
 | [{ letter: "a", number: 1 }, |
 |  { letter: "b", number: 2 }] |
 *------------------------------*/
ClickHouse arrayZip 함수
WITH Combinations AS
    (
        SELECT
            ['a', 'b'] AS letters,
            [1, 2, 3] AS numbers
    )
SELECT arrayZip(letters, arrayResize(numbers, length(letters))) AS pairs
FROM Combinations;
   ┌─pairs─────────────┐
1. │ [('a',1),('b',2)] │
   └───────────────────┘
배열 집계 BigQuery 배열을 다시 테이블로 펼치려면 UNNEST 연산자가 필요합니다
WITH Sequences AS
  (SELECT [0, 1, 1, 2, 3, 5] AS some_numbers
   UNION ALL SELECT [2, 4, 8, 16, 32] AS some_numbers
   UNION ALL SELECT [5, 10] AS some_numbers)
SELECT some_numbers,
  (SELECT SUM(x)
   FROM UNNEST(s.some_numbers) AS x) AS sums
FROM Sequences AS s;

/*--------------------+------*
 | some_numbers       | sums |
 +--------------------+------+
 | [0, 1, 1, 2, 3, 5] | 12   |
 | [2, 4, 8, 16, 32]  | 62   |
 | [5, 10]            | 15   |
 *--------------------+------*/
ClickHouse arraySum, arrayAvg, … 함수 또는 arrayReduce 함수의 인수로 사용할 수 있는 기존 집계 함수 이름 90여 개 중 하나
WITH Sequences AS
    (
        SELECT [0, 1, 1, 2, 3, 5] AS some_numbers
        UNION ALL
        SELECT [2, 4, 8, 16, 32] AS some_numbers
        UNION ALL
        SELECT [5, 10] AS some_numbers
    )
SELECT
    some_numbers,
    arraySum(some_numbers) AS sums
FROM Sequences;
   ┌─some_numbers──┬─sums─┐
1. │ [0,1,1,2,3,5] │   12 │
   └───────────────┴──────┘
   ┌─some_numbers──┬─sums─┐
2. │ [2,4,8,16,32] │   62 │
   └───────────────┴──────┘
   ┌─some_numbers─┬─sums─┐
3. │ [5,10]       │   15 │
   └──────────────┴──────┘
마지막 수정일 2026년 6월 10일