Programming/Oracle

테이블 생성시 NULL 컬럼의 적용

초록깨비 2008. 12. 2. 13:26
728x90

 

테이블을 생성할 때 NULL 컬럼의 적용에 대해서 알아본다.

 

(KEY WORD : INDEX 활용, 인덱스, NULL )

 

 

  • 테이블의 컬럼을 설계할 때 기본값(Default Value) ‘NULL’로 할 것인가 아니면 임의의 값(: X, 0, A)으로 할 것인가는 인덱스 처리와 밀접한 관계를 가진다. 만약 분포도가 양호한 컬럼이 ‘NULL’로 정의되어 있다면 우리는 어쩔수 없이 전체 테이블을 엑세스하거나 다른 조건의 도운을 받을 수 밖에 없다. 또한 너무 많은 로우를 가진 경우에 컬럼을 ‘NULL’로 지정하지 않고 인덱스를 가지고 있다면 넓은 범위를 인덱스로 처리하게 됨으로써 오히려 불리하게 된다.
     
  • 다음의 SQL을 보자

          SELECT ORD_NO, ORD_DATE, ITEM, ORD_QTY
          FROM ORDER
          WHERE ORD_DATE IS NOT NULL
          ORDER BY ORD_DATE
  • SQL과 동일한 결과를 추출하지만 아래 SQL처럼 전체 데이블을 읽어 정렬하지 않고서도 인덱스를 경유하도록 함으로써, 인덱스 순서대로 엑세스하다가 운반단위가 채워지면 멈추도록 하여 수십, 수백배 이상의 수행속도를 향상시킬 수 있다.

            SELECT ORD_NO, ORD_DATE, ITEM, ORD_QTY
            FROM ORDER
            WHERE ORD_DATE >

 

  • 만약 비교되는 컬럼이 숫자 타입이라면 다음과 같이 사용해야 한다.

            SELECT ORD_NO, ORD_DATE, ITEM, ORD_QTY
            FROM ORDER
            WHERE ORD_NO > 0

 

  • 위에서 ‘IS NOT NULL’로 사용된 경우는 인덱스를 사용하도록 유도할 수 있으나 다음과 같이 ‘NULL’값을 가지는 로우를 가지는 로우를 찾고자 할 경우에는 대체할 방법이 없다.

SELECT ORD_DEPT, ORD_DATE
FROM ORDER
WHERE STATUS IS NULL

 

 

 

  • 컬럼의 값이 ‘NULL’인 로우가 많다면 손해가 되지 않으나 (, 많다면 어차피 전체 테이블 스캔 방식이 더 낳기 때문이다) 적다면 손해는 크다. 이의 개선을 위해서는 다음과 같은 테이블을 생성하는 시점에 기본값(Default Value)를 지정해서 원천적으로 NULL이 들어가지 못하게 하는 것이 중요하다.

CREATE TABLE ORDER
( …………………………….
STATUS CHAR(2) DEFAULT ‘00’,
………………………….. )

 

  • 위와 정 반대의 경우도 발생할 수 있다. , ORDER 테이블은 10,000 개의 로우를 가지고 있고 ‘STATUS’ 컬럼은 컬러값이 ‘E’인 경우를 제외하면 좁은 분포도를 가진다. , ‘E’ 값이 전체 로우의 약 80%를 차지 한다는 것이다. 이럴 경우에 ‘E’ NULL로 바꾸게 되면 인덱스에서 80%에 해당하는 로우가 줄어든다. 또한, ‘E’인 경우를 엑세스하기 위해서는 자연스럽게 ‘IS NULL’로 비교하게 되어전체 테이블 스캔방식을 유도하여 랜덤 엑세스를 줄여 성능을 향상시킬 수 있다.

 

  • 더 자세한 내용은대용량 데이터베이스 솔루션 I page 18’을 참조하기 바란다.

 

728x90