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