데이터 웨어하우스에서 데이터 큐브(data cube)를 효율적으로 계산하기 위해서는 단순한 무차별 연산보다 체계적인 최적화 기법이 필요합니다. 대표적인 일반 최적화 기법은 다음 네 가지입니다.
1. 정렬, 해싱, 그룹핑 활용
차원 속성(dimension attribute)에 정렬(sorting), 해싱(hashing), 그룹핑(grouping) 연산을 적용하면 관련된 튜플들을 재배열하고 클러스터링할 수 있습니다.
큐브 계산에서 집계(aggregation)는 동일한 차원 값 집합을 공유하는 튜플(또는 셀) 단위로 수행됩니다. 따라서 이러한 데이터에 접근하고 그룹으로 묶기 위해 정렬, 해싱, 그룹핑 기능을 적극적으로 활용하는 것이 집계 연산의 속도를 높이는 데 필수적입니다.
예시: 지점(branch), 일자(day), 품목(item)별 총 매출을 산출한다면, 튜플을 지점별로 먼저 정렬하고, 다시 일자별로 정렬한 후 품목명을 기준으로 그룹핑하는 것이 훨씬 효율적입니다. 대용량 데이터셋에서 이런 연산을 효과적으로 구현하는 방법은 데이터베이스 연구 분야에서 오랫동안 개발되어 왔으며, 그 성과를 데이터 큐브 계산에 그대로 활용할 수 있습니다.
2. 동시 집계와 중간 결과 캐싱
큐브 계산 시 기본 팩트 테이블(base fact table)에서 직접 집계하는 대신, 이미 계산된 하위 수준의 집계 결과를 재사용하여 상위 수준의 집계를 도출하는 것이 바람직합니다.
또한 캐싱된 중간 계산 결과를 활용해 여러 집계를 동시에 수행하면 비용이 많이 드는 디스크 I/O 작업을 크게 줄일 수 있습니다.
예시: '지점별 매출'을 계산할 때, 더 낮은 수준의 큐보이드(cuboid)인 '지점·일자별 매출' 계산 과정에서 얻은 중간 결과를 활용할 수 있습니다. 이 방법을 확장하면 상각 스캔(amortized scan), 즉 디스크 읽기를 최소화하기 위해 가능한 한 많은 큐보이드를 한 번의 스캔으로 동시에 계산하는 기법도 구현할 수 있습니다.
3. 복수의 자식 큐보이드가 있을 때는 가장 작은 것부터 집계
여러 개의 자식 큐보이드(child cuboid)가 존재하는 경우, 원하는 부모(즉, 더 일반화된) 큐보이드를 계산할 때는 이전에 계산된 자식 큐보이드 중 가장 작은 것을 사용하는 것이 일반적으로 더 효율적입니다.
예시: 지점별 매출 큐보이드 CBranch를 계산해야 하는데, 이미 계산된 두 개의 큐보이드 C{Branch, Year}와 C{Branch, Item}가 있다고 가정해 보겠습니다. 서로 다른 품목(item)의 수가 서로 다른 연도(year)의 수보다 훨씬 많다면, C{Branch, Item}보다는 C{Branch, Year}로부터 CBranch를 계산하는 것이 더 효율적입니다.
4. 아프리오리(Apriori) 가지치기로 아이스버그 큐브 효율적 계산
아이스버그 큐브(iceberg cube)를 효율적으로 계산할 때는 아프리오리 가지치기(pruning) 기법을 활용할 수 있습니다. 데이터 큐브 관점에서 아프리오리 속성은 다음과 같이 정의됩니다.
아프리오리 속성: 어떤 셀이 최소 지지도(minimum support) 조건을 만족하지 않는다면, 그 셀의 모든 하위 항목(더 세분화된 버전) 역시 최소 지지도를 만족하지 못한다.
이 속성을 활용하면 아이스버그 큐브의 계산량을 획기적으로 줄일 수 있습니다. 아이스버그 큐브의 명세에는 아이스버그 조건, 즉 물리적으로 저장(materialize)할 셀에 대한 제약 조건이 포함됩니다. 일반적인 아이스버그 조건은 셀이 최소 지지도 임계값(최소 개수 또는 최소 합계 등)을 충족해야 한다는 것입니다. 이 경우, 지지도 조건을 벗어난 셀의 하위 항목들은 탐색 자체를 생략함으로써 불필요한 연산을 제거할 수 있습니다.
마무리
이 네 가지 기법은 각각 독립적으로 적용할 수 있지만, 실제 큐브 계산 파이프라인에서는 함께 조합했을 때 시너지가 극대화됩니다. 정렬과 그룹핑으로 데이터 접근을 최적화하고, 캐싱된 중간 결과를 재활용하며, 가장 작은 자식 큐보이드부터 집계하고, 마지막으로 아프리오리 가지치기로 탐색 공간을 줄이는 것이 고효율 큐브 계산의 핵심 전략입니다.