# Tibero Columnar Compression

## 개요

TCC는 압축률 향상과 디스크 I/O 감소에 도움을 주는 데이터 저장 방식입니다.&#x20;

TCC를 이용하면 기존의 방식(row의 column들을 연속으로 배치하는 것)을 대신하여 테이블의 각 컬럼들을 개별적으로 수집하여 연속으로 저장합니다.

아래와 같이 컬럼을 연속으로 배치할 경우, 동일한 데이터 패턴이 반복되어 RLE(Run-Length Encoding), LZ4(Lempel-Ziv 4), gzip(GNU zip), bzip2(block zip version 2)와 같은 압축 기법에 매우 효과적입니다.

<figure><img src="https://content.gitbook.com/content/zj5CE3vb55thKXRdYI8S/blobs/8Luc4ytgEmUEhB8iho1K/4.png" alt=""><figcaption><p>그림 1. TCC 구성(Compression Unit)</p></figcaption></figure>

### TCC 장점

* 압축률이 크게 향상됩니다. \
  데이터 패턴에 따라 차이가 나지만, 일반적인 OLAP 비즈니스 환경에서 4:1\~10:1의 압축률 향상을 기대할 수 있습니다.
* 압축률이 향상되므로 전체 I/O가 줄어듭니다.\
  I/O가 성능의 병목인 경우 성능향상을 도모할 수 있습니다. 또한 ZetaData는 SSVR 인스턴스에서 압축을 해제하기 때문에 DB 노드의 자원을 소모하지 않습니다. Storage 노드의 CPU 자원은 일반적으로 여유가 있는 경우가 많습니다.
* 컬럼별로 배치되므로 불필요한 컬럼을 읽지 않습니다. \
  전체 컬럼수와 비교하여 필요한 컬럼이 적을 경우 I/O수행 횟수를 줄일 수 있습니다.

아래의 경우에 TCC를 사용하면 효과적입니다.

#### **Update(**&#xB610;는 **delete)**&#xAC00; 드물게 발생하는 테이블

위에서 설명한 바와 같이 TCC로 구성된 테이블에 대해 update가 일어나면 성능이 저하됩니다. 따라서 주로 DPL/DPI를 통해 대량으로 로딩하고, 데이터 라이프 사이클(Life Cycle)에 따라 테이블 전체를 따로 저장하거나 폐기하는 용도로 매우 적합합니다.

#### **Full table scan**이 빈번하게 발생하는 테이블

주로 사용되는 쿼리가 Full table scan인 경우에 TCC를 추천합니다. Full table scan은 선택도(Selectivity) 에 따라 결정될 수도 있고, aggregation 사용 여부에 따라 결정될 수도 있습니다.

#### 데이터 길이나 패턴이 일정하거나 비슷한 테이블

데이터 길이나 패턴이 일정하거나 비슷한 테이블의 경우 RLE, LZ4, gzip, bzip2와 같은 압축을 적용했을 때 좋은 압축률을 기대할 수 있습니다. 또한 로딩할 때 압축률이 거의 일정하면, 재압축 횟수가 줄어들어 로딩 속도도 향상됩니다.

#### **Projectivity**가 큰 테이블

TCC 사용은 테이블의 일부 컬럼만 필요로 하는 경우에 특히 효과적입니다. 필요하지 않은 컬럼에 해당하는 CU(Compression Unit)는 읽지 않습니다. 만약, row-oriented로 저장되어 있다면 필요로 하는 컬럼 개수와 관계없이 row의 전체 컬럼을 읽어야 합니다. 따라서 상대적으로 읽어야하는 블록 숫자가 늘어납니다.

***

## 초기화 파라미터 <a href="#bookmark111" id="bookmark111"></a>

아래는 TCC와 관련한 초기화 파라미터에 대한 설명입니다. CC\_CU\_BLKCNT는 시스템 파라미터이고 나머지 파라미터들은 세션 파라미터입니다.

<table><thead><tr><th width="280">파라미터</th><th>설명</th></tr></thead><tbody><tr><td>CC_CU_BLKCNT</td><td><p>CU(Compression Unit)가 가질 수 있는 최대 블록 개수입니다.</p><p>보통은 큰 CU가 압축에 유리하지만, 어느 정도 이상이 되면 많이 차이가 나지 않습니다. 불필요하게 CU가 크면 반복적인 압축 해제가 있는 경우 불리하게 작용할 수도 있습니다.</p><p>DB_FILE_MULTIBLOCK_READ_COUNT보다 작게 설정하는 것을 권장합니다. (기본값: 4, 범위: 1 - 32)</p></td></tr><tr><td>CC_CU_PCTUSE</td><td>CU에 들어갈 최소 용량 비율입니다.<br>CU를 구성할 때 최소 이 비율 이상을 채웁니다. 이 값이 크면 공간 낭비를 막을 수 있는 반면, 로딩할 때 재압축이 많아져서 성능이 저하될 수 있습니다. (기본값: 95, 범위: 0 - 99)</td></tr><tr><td>CC_TYPICAL_ROW_SIZE</td><td><p>압축될 데이터의 일반적인 row 크기입니다.</p><p>처음 압축을 시작할 때에 힌트로 사용됩니다. 이 값과 CC_EXPECTED_RATE를 이용해서 한 CU에 몇 개의 row가 들어갈지 예측해서 압축을 더 빠르게 진행시킬 수 있습니다. (기본값: 100, 범위: 3 - 1000)</p></td></tr><tr><td>CC_EXPECTED_RATE</td><td><p>압축될 데이터의 일반적인 압축 비율입니다(힌트).</p><p>CC_TYPICAL_ROW_SIZE와 함께 처음 CU를 구성할 때 쓰입니다. 이후 CU에 대한 예측은 직전 CU의 결과를 이용합니다.</p><p>(기본값: 25, 범위: 1 - 100)</p></td></tr><tr><td>CC_CU_WRITEOUT_THRESHOLD</td><td><p>CC_CU_WRITEOUT_THRESHOLD는 단일 블록이 쓰기 작업을 진행하기 위해 충족해야 하는 최소 채움 비율을 지정하는 설정입니다. 즉, 블록의 데이터가 설정된 비율 이상 채워졌을 때에만 해당 블록이 디스크에 기록됩니다.</p><p>(기본값: 85, 범위: 0 - 99)</p></td></tr></tbody></table>

***

## **TCC** 테이블 생성 명령어

CREATE TABLE 명령을 수행할 때 아래의 옵션을 주어서 TCC 테이블을 만들 수 있습니다.

```sql
CREATE TABLE {table-name} COMPRESS FOR QUERY LOW
```

컬럼 압축 중에서는 OLTP성 업무로 인한 성능 손실을 최대한 막을 수 있는 레벨입니다.

```sql
CREATE TABLE {table-name} COMPRESS FOR QUERY HIGH
```

중간 정도의 압축 레벨입니다. 압축/해제의 성능도 중간 정도입니다.

```sql
CREATE TABLE {table-name} COMPRESS FOR ARCHIVE LOW
```

보다 높은 압축 레벨입니다. 압축/해제의 성능은 다소 떨어집니다.

```sql
CREATE TABLE {table-name} COMPRESS FOR ARCHIVE HIGH
```

최대 압축률입니다. 압축/해제의 성능도 제일 낮습니다.

{% hint style="info" %}
**참고**

컬럼 압축이 아닌 기존의 기본 압축 방식을 적용하기 위해서는 COMPRESS까지만 설정합니다.&#x20;
{% endhint %}

아래는 옵션을 사용한 예입니다.

```sql
CREATE TABLE T(A NUMBER) COMPRESS FOR QUERY HIGH
```

***

## **TCC** 사용 주의사항

TCC는 row-oriented 저장구조에 비해 장점만 있는 것은 아니기 때문에 잘못 사용하면 성능에 큰 손실을 입을 수 있습니다. 아래와 같은 경우는 주의해야 합니다.

### **Update(**&#xB610;는 **Delete)**&#xAC00; 빈번하게 발생하는 테이블

TCC로 저장된 테이블에 update가 수행되면, 압축이 해제되고 해당 row는 row-oriented 로 변경됩니다. 또한 많은 경우에 row 단위로 읽는 방식보다 더 많은 블록을 읽어야 하는 특성이 있습니다. 예를 들어 UPDATE SET A=1, B=2 WHERE C=3을 처리할 때에 row-oriented로 저장되어 있으면 한 블록만 읽으면 되지만, TCC로 저장되어 있으면 세 개의CU를 읽어야 합니다.

CC\_CU\_BLKCNT가 클 경우는 다음과 같은 상황에서 더욱 문제가 될 수 있습니다. 하나의 row를 처리하기 위해서 각 CU마다 CC\_CU\_BLKCNT만큼의 블록 I/O가 필요합니다. 따라서 압축효율의 큰 차이가 없다면, 적정 수준의 CC\_CU\_BLKCNT를 사용하는 것이 좋습니다.

### 인덱스를 통한 접근이 많은 테이블

인덱스를 통한 접근 시 항상 CU 단위로 압축을 해제합니다. (단, 연속된 rowid에 대해서는 압축 해제된 내용을 재사용합니다. 각각의 Row마다 항상 압축을 해제하는 것은 아닙니다.)&#x20;

따라서 인덱스를 통한 접근 시 압축 해제가 빈번하게 발생할 수 있으므로, 성능 저하 가능성을 고려해야 합니다.  인덱스를 통한 접근과 같이, TCC 저장방식은 row 단위로 접근하는 모든 경우에 비효율적입니다.

### 제약조건

* TCC가 걸린 테이블에 drop column, set unused column, rowid를 사용하는 table redefinition이 불가능합니다.
* TCC가 걸린 테이블에 bitmap index 생성이 불가능합니다.
* LOB, LONG, XML, 사용자 정의형(nested table, varray, object 등) column type이 존재하는 테이블에 TCC 사용 불가능합니다.
* 암호화된 테이블에 DPI 수행 시 압축이 되지 않습니다.
* TCC가 걸린 테이블에 Merge, Split partition 수행 시 Update Global Indexes(UGI), Update Indexes(UI) 사용이 불가능합니다.
