3.클러스터링의 활용

  • 시스템의 부하는 거의 넓은 범위를 처리하는 경우에 발생하므로 이런 경우의 해결이 곧 RDB를 이용해 대용량 시스템을 구축할 수 있느냐 하는 문제와 직결됨
  • 넓은 범위를 처리하는 경우의 문제를 가장 효율적으로 개선하기 위한 클러스터링 확인

3.1 클러스터의 구조 및 특징

  • 클러스터는 테이블이나 인덱스처럼 저장공간을 가지고 있는 하나의 오브젝트
  • 클러스터와 테이블, 각각은 별도의 독립적인 오브젝트이지만 개념적인 종속성을 가짐
    {section}
    {column:width=300}

create cluster mechultc1 (deptno number(2))
size 8600
tablespace test_data_sp ;

create index mechultc1_idx on cluster mechultc1
tablespace test_index_sp ;

create table mechultc1_tbl (empno varchar(04), 
                       deptno number(02),
                       sale_date varchar(8),
                       qty number)
cluster mechultc1 (deptno);

{column}
{section}

클러스터 인덱스와 보통 인덱스의 비교


출처 : 이화식(대용량데이터베이스솔류션)PPT자료

인덱스(Index)클러스터(Cluster)
인덱스는 테이블의 로우의 ROWID별로
하나씩의 인덱스를 가짐
클러스터는 클러스터링된 값(Cluster Key)마다
하나씩의 클러스터 인덱스 로우를 가짐
NULL 값을 저장하지 않음NULL 값을 저장함
  • Cluster Index : 클러스터링된 컬럼에 생성된 인덱스
    • 클러스터안의 행의 위치를 나타내기 위해 사용된다.
    • 클러스터된 테이블안에 DML을 사용하기 전에 반드시 Cluster Index를 생성해야 한다. Cluster Index가 없다면 데이터를 클러스터 테이블에 올릴 수 없다.
    • 테이블 인덱스처럼 Cluster Index도 별도의 tablespace에 저장할 수 있다.
  • Cluster key : 클러스터된 테이블이 공유하는 컬럼 또는 컬럼의 집합
    • 클러스터키를 구성할 수 있는 컬럼의 수는 최대 16개.
    • 실제 최대 개수는 datablock에 따라 틀리다(클러스터키는 데이터블럭의 1/3을 초과할 수 없기때문)
    • 클러스터키는 long또는 long raw컬럼을 가질 수 없다.
  • Cluster header : 클러스터된 값이 처음 시작되는 Rowid
    • 클러스터를 액세스경는 클러스터인덱스와 클러스터 테이블 경유하기 때문에 최소 2번의 I/O가 발생한다.

클러스터링이란?

클러스터링이란 어떤 정해진 컬럼을 기준으로 동일한 값을 가진 모든 로우를 같은 장소에 저장하여 같은 값을 가지는 여러 로우를 액세스할 때 랜덤액세스를 최소화함으로써 액세스효율을 개선시키는 물리적인 저장기법이다

Note

  • 클러스터의 효과는 클러스터링 팩터(Clustering Factor)의 향상에 있다
  • 클러스터링 팩터란 엑세스하고자하는 데이터이 모여있는 정도를 말한다.
  • 다량의 범위를 인덱스로 액세스하는 것과 동일한 양을 스캔방식으로 액세스하는 것의 차이는 약 10배 정도가 된다.
  • 적절하게 지정한 클러스터링은 약 5배~8배 가량의 효율을 가져올 수 있다.

궁금한점 : 일반 인덱스테이블의 클러스터링팩터를 좋게 한다면 클러스터링 테이블액세스와 비교가 될까?
단일 테이블 클러스터 테스트

3.1.1 클러스터링의 종류

{section}
{column:width=50%}

단일테이블 클러스터링
  • 지정된 클러스터에 하나의 테이블만 생성
  • 넓은 범위의 처리를 스캔방식으로 유도하기 위해 사용

{column}
{column:width=50%}

다중테이블 클러스터링
  • 지정된 클러스터에 두 개 이상의 테이블을 생성시키는 것을 말한다.
  • 같은 클러스터 컬럼값을 가진 각 테이블의 로우는 정해진 장소에 같이 저장되므로 여러 테이블을 조인하는 속도를 향상시키고자 할 때 활용한다.
  • Full table scan 시에는 불리함(클러스터내의 블록 내에 다른 테이블의 데이터가 있기 때문)

{column}
{section}

3.2 클러스터컬럼의 선정

3.2.1 클러스터의 부하

  • 클러스터링은 단지 검색의 효율성을 높여줄 뿐
  • 입력, 수정, 삭제 시는 추가적인 부하가 발생함.
    • 입력 시의 부하
      • 클러스터링 테이블은 값에 따라 정해진 위치가 있어서 일반 테이블에 추가적인 부하가 있을 수 밖에 없다.
      • 클러스터링 테이블의 저장은 각 로우들의 값에 따라 프리리스트를 요구하는 횟수도 증가하며 최악의 경우 저장되는 블록이 모두 틀릴 수 도 있다.
    • 수정 시의 부하
      • 클러스터링 테이블에 있는 컬럼을 수정하는 경우
      • 클러스터컬럼의 값을 수정하는 경우 :
        수정작업에 따른 부하는 증가하지 않으나 많은 클러스터 체인이 발생하여 클러스터 팩터를 나쁘게 한다.
    • 삭제 시의 부하
      • 로우를 삭제하는 것은 문제가 되지않는다.
      • 클러스터 테이블을 삭제할 때 내부적으로 delete작업을 하므로 많은 부하를 유발한다.
      • 클러스터는 여러 테이블을 포함하고 있기 때문이다.
      • 클러스터내의 모든 테이블을 삭제할 경우 DROP CLUSTER, TRUNCATE CLUSTER명령을 사용하면 보다 신속한 수행속도를 보장받을 수 있다.

클러스터링된 테이블의 삭제방법 - 클러스터내의 테이블 삭제의 경우

삭제할 내용을 충분히 담을 수 있는 큰 롤백 세그먼트를 가지고 있어야 하며 작업전에 다음과 같은 명령어로 별도(충분한)의 롤백 세그먼트를 지정하여야 한다.


SET TRANSACTION USE ROLLBACK SEGMENT large_rollback_segment_name;

만약 충분히 큰 롤백 세그먼트를 가지고 있지 않다면 분할하여 로우를 삭제시킨 후 테이블을 삭제시켜야 한다.


DELETE FROM table WHERE ROWNUM < 1000000;

3.2.2 클러스터컬럼의 선정절차

  • 클러스터 컬럼의 후보선정
    • 6 블럭이상의 테이블
    • 다량의 범위를 자주 엑세스해야 하는 경우
    • 인덱스를 사용한 처리가 부담이 되는 넓은 분포도
    • 여러 개의 테이블이 빈번한 조인을 일으킬 때
    • 반복컬럼이 정규화 작업에 의해 어쩔 수 없이 분할된 경우
    • UNION, DISTINCT, ORDER BY, GROUP BY 가 빈번한 컬럼이면 고려해 볼 것
    • 수정이 자주 발생하지 않는 컬럼
    • 처리범위가 넓어 문제가 발생되는 경우는 단일 테이블 클러스터링
    • 조인이 많아 문제가 발생되는 경우는 다중 테이블 클러스터링
  • 클러스터 컬럼의 고려사항
    • 데이타 처리(입력,수정,삭제)에 오버헤드 발생 주의
    • 인덱스로도 충분한 범위는 클러스터링 효과가 없음
    • 클러스터 키는 수정이 빈번하지 않을 것
    • 각종 엑세스형태에 대해 인데스와 적절한 역할 분담
    • 클러스터링은 기존의 인덱스의 수를 감소시킴(인덱스 재구성)
    • 클러스터 SIZE parameter 가 중요
      • Cluster key value하나와 관련된 모든 행들을 저장하는데 필요한 공간의 평균크기를 정한다.
      • Size가 너무 높게 설정되면 블록내 사용되지 않는 공간이 많아진다.
      • Size가 너무 낮게 설정되면 동일한 cluster key value를 같는 행들이 다른 Cluster block에 위치하게 된다. (체인닝)
    • 클러스터 키별 로우 수의 편차가 심하지 않을 것
    • 클러스터에 데이타 입력시 로우가 적은 테이블부터 실시할 것
    • 클러스터링된 테이블 조인시 로우 수의 역순으로 FROM 절에 기술할 것
    • 클러스터 키를 첫번째로 하는 인덱스는 생성하지 말 것
  • 클러스터 컬럼의 후보가 결정되면 그 효율성을 진단해 보아야 한다.
  • 목표 수행속도를 보장받을 수 있는 지를 진단해 보아야 한다.
  • 클러스터링 컬럼의 결정은 '인덱스의 선정'에서 실시했던 작업을 통해 인덱스와 더불어 종합적인 판단을 해야한다.
  • 클러스터링에 필요한 파라미터를 적절히 조정한다.

3.2.3 클러스터링 형태의 판단기준

  • 전체테이블 클러스터링 고려사항
    • 각 테이블이 항상 조인되어 사용된다면 가장 이상적인 조인속도를 보장한다.
    • 항상 조인되어 사용하지 않는 경우 굳이 클러스터링을 하면 독립적으로 사용 시 효과를 보지 못한다.
    • 향후 예상되는 액세스형태를 감안할 필요가 있다.
    • 일반적으로 테이블이란 독립적인 특성을 가지고 독립적인 액세스형태가 나타난다.
  • 일부테이블 클러스터링
    • 각 테이블의 독립성을 무시할 수 없는 경우 결합도가 강한 테이블끼리만 클러스터링할 필요가 있다.
  • 단일테이블 클러스터링
    • 조인의 효율성 향상을 위한 다중 클러스터링은 가능한 피하는 것이 좋다.
    • 넓은 범위의 처리를 스캔방식으로 유도한다.

3.2.4 클러스터링 테이블의 체인

  • 클러스터링 테이블에서의 체인은 로우의 증가로 인해 체인이 발생한다.
  • 클러스터링 테이블에서의 체인된 로우는 같은 블록에 모여서 저장된다.
  • 클러스터링 사이즈
    {tip:titel=클러스터링 사이즈구하기}
  • 클러스터링 사이즈는 클러스터효율성에 많은 영향을 미친다.
 
	∑_(table=1)^n▒(table 평균로우길이* 클러스터 키당 평균 로우 수) 


쉽게 이렇게도 한다.

 	
(table평균로우길이*클러스터 키당 평균 로우수) * 1.1

3.3 클러스터 사용을 위한 조치

  • 클러스터 키 컬럼을 첫번째로 하는 인덱스를 생성시키지 말 것
  • 클러스터가 반드시 사용되어지기를 원한다면 액세스 경로를 고정시킬 수 있다.

{section}
{column:width=33%}


SELECT SUM(COUNT(*))
FROM MECHULT
WHERE SALE_DATE BETWEEN '20000101'
                    AND '20071231'
AND SALE_DEPT= 20

{column}
{column:width=33%}


SELECT SUM(COUNT(*))
FROM MECHULT
WHERE SALE_DATE BETWEEN '20000101' 
                    AND '20071231'
AND RTRIM(SALE_DEPT) = 20

{column}
{column:width=33%}


SELECT /*+ CLUSTER(MECHULT) */
SUM(COUNT(*))
FROM MECHULT
WHERE SALE_DATE BETWEEN '20000101' 
                    AND '20071231'
AND SALE_DEPT = 20

{column}
{section}

  • 인덱스가 SALE_DATE + SALE_DEPT 결합인덱스인 경우 우선순위에 의해서 결합인덱스를 이용한 액세스를 할 것임
  • 서프레스를 통한 인덱스사용제한이나 옵티마이져 옵션으로 클러스터링 사용을 유도

클러스터의 특징정리

  • 엑세스기법이 아니라 엑세스 효율향상을 위한 물리적 저장기법
  • 지정된 컬럼값의 순서대로 실제 로우를 저장시키는 방법
  • 하나 혹은 그 이상의 테이블을 같은 클러스터내 저장 가능
  • 검색의 효율을 높여주나 입력, 수정, 삭제시는 부하 증가
  • 분포도가 넓을 수록 오히려 유리 (인덱스의 단점을 해결 5~7배)
  • 분포도가 넓은 테이블의 클러스터링은 저장공간 절약

문서에 대하여