[ClickHouse] INDEX 구조와 동작 원리 - ③
Clickhouse의 특성 상 특정 column에 맞는 Index를 생성하는 방법이 아닌, Query에 맞는 Primary Key를 선언해야 합니다. 따라서, 사용하고자 하는 Query에 따라 Primary Key가 달려져야 하며, ClickHouse는 이를 충족할 세 가지 대안을 제시합니다.
1) Primary Key가 다른 Copy Table 생성
2) Primary Key가 다른 Materialize View 생성
3) 기존 Table에 Primary Key가 다른 Projection을 추가
먼저, 1) Primary Key가 다른 Copy Table 생성 하는 방법에 대해 알아봅니다.
위 그림은 UserID를 Index로 사용하는 Query와 URL을 Index로 사용하는 Query을 기준으로, Table을 분리 시켜둔 그림입니다. 두 테이블의 Primary Key는 각각 (UserID, URL), (URL, UserID)로 선행, 보조 키의 순서가 바뀌어 선언되었습니다.
이 경우 각각의 Query는 해당 Query에 적합한 Table에 명시적으로 전송되어야 하며, 두 Table 간의 Sync(동기화) 작업이 필요합니다. 따라서 두 테이블에 대한 Insert 작업이 이루어져야 합니다.
PK와 Table 명만 변경된 두 개의 Table을 동시에 관리해야 하는 불편함이 있기 때문에, Copy Table보다 2 ) Primary Key가 다른 Materialize View 생성 의 방법이 좀 더 좋아 보입니다. 아래는 그에 대한 그림입니다.
위 그림에서는 기존 Table을 통해 Materialized View를 생성하여 ClickHouse 내부적으로 Table을 생성하게 합니다. 이 방법은 두 Table (기존 Table, 내부 Table)이 자동으로 Sync가 맞춰집니다. 따라서 기존 Table만 관리하면 됩니다. Copy Table 방법보다 편리해 보입니다. 그러나 이 방법 역시 Query가 다른 경우마다 다른 Table을 참조해야 한다는 번거로움은 여전합니다.
마지막 방법은 3) 기존 Table에 Primary Key가 다른 Projection을 추가 하는 방법입니다.
Projection을 추가해서 사용하는 방법은 내부적으로 Table이 생성되고 자동으로 Sync가 맞춰지는 것까지는 Materialized View와 같습니다. 그러나 같은 이름의 Table을 참조하더라도 사용되는 Index에 따라 ClickHouse의 Optimizer에 의해 자동으로 최적의 Table을 선택한다는 큰 장점이 있습니다. 아래는 그에 대한 그림입니다.
최종적으로 Index에 대해서 정리하자면 아래와 같습니다.
========================================================================
1. Index는 Primary Key에 따라 결정됩니다.
2. Primary Key가 복합 키인 경우, 보조 키 열에 대한 필터링은 경우에 따라 큰 이점을 얻지 못합니다.
3. Primary Key는 가급적 단일 Key로 사용하고(Index Memory 사용량을 줄임), 대신 여러 Index를 사용하는 것이 좋습니다. (ex. Projection)
4. Primary Key로 잡으려는 Column들의 카디널리티 차이를 명확하게 알고 있고, Column의 카디널리티 간의 차이가 큰 경우에는 PK를 복합 키로 선언하고, PK Column들을 카디널리티 별로 오름차순하여 정렬하는 것이 가장 이상적입니다. (Key Column 간의 카디널리티 차이가 클수록 복합 키의 Column 순서가 중요함 -> 압축 비율과 I/O 사용량이 줄어 Query 응답 시간이 빨라짐)
========================================================================
참조 ) https://clickhouse.com/docs/en/optimize/skipping-indexes