울회사 권병준 대리가 개발팀에 뿌린 가이드. 실수하기 쉬운 것임...
---------------------------------
안녕하세요. DB개발팀의 권병준입니다.. 오늘도 찾아온 주의사항 한마디입니다.
역시나 길게 글 읽기 싫어하시는 분들을 위해 요약해서 한줄로 먼저 말씀드리겠습니다.
WHERE 조건에서 같은 컬럼에 대해 IS NOT NULL 조건과 <, >, <>, ANS SO ON.. 등의 조건을
같이 사용하지 마십시요.
-----------------------------------------------------------------------------
이제 설명 부분..
SP 검수하다보면 간간히 (A를 컬럼명이라고 가정합시다)
WHERE A IS NOT NULL AND A >= @YESTERDAY AND A <= @TODAY
와 같은 조건이 있는 경우가 있습니다.
물론, 해석은 A 가 NULL이 아니면서 어제와 오늘 사이의 값에 대한 조회.. 라는 건데,
저렇게 사용할 필요가 전혀 없습니다.
여기서 NULL 이라는 것에 대해 다시 한 번 재조명을 해보도록 하지요.
NULL 이라는 것은 값없음(이 아니라!) 미확정값이라는 뜻입니다.
아직 해당 컬럼에 값이 정해져있지 않다는 얘기죠. WHERE 조건에서
WHERE A >= @YESTERDAY 라고 조건을 주게 되면 당연히 어제 이후로의 확정된! 값에
대한 것만 조회를 해달라는 의미입니다. 여기서 미확정값은 당연히 제외가 되겠죠.
고로 저렇게 확정된 값에 대한 조회조건을 주면서 또다시 미확정된 값을 제외하라는 조
건을 주는건 CPU 부담만 증가시킬 뿐입니다. (Bookmark Lookup시에 꽤 부담을 주게 됩
니다.)
실제 간단한 실험을 통해서 비용적인 측면의 비교를 한 번 해 보겠습니다.
하나의 테이블을 만들고 여기에 테스트 값을 넣어줍니다.
CREATE TABLE NULL_TEST (
SEQ INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
NULL_COL INT NULL
)
DECLARE @CNT INT
SET @CNT = 1
WHILE @CNT < 5000
BEGIN
INSERT INTO NULL_TEST VALUES (NULL)
INSERT INTO NULL_TEST VALUES (@CNT)
SET @CNT = @CNT + 1
END
10000개의 데이터가 생성이 되었습니다. 여기서 제가 위에 말한 조회조건대로 IS NOT NULL이라는 조건을 추가로 준 것과 아닌 것에 대해서 각각 간단하게 조회를 해 봅니다.
SELECT * FROM NULL_TEST WHERE NULL_COL < 10 AND NULL_COL IS NOT NULL
SELECT * FROM NULL_TEST WHERE NULL_COL < 10
물론 결과값은 같습니다. 하지만 조회에 해당되는 비용은 다르게 나옵니다.아래 그림을 봐 주십시요.
위의 쿼리와 아래의 쿼리 비용이 63.64% VS 36.36%로 차이가 나는 것을 보실 수 있을 겁
니다. 안 써도 되는 컬럼 추가로 인해 비용 차이가 이만큼이나 벌어졌습니다. 행 수가
많아지면 많아질수록 이 격차는 더욱 커집니다.
SP 작성하실 때에 여러분의 주의를 부탁드립니다. ^^
----------------------------------------------------------------------------
이건 좀 더 알고 싶으신 분들을 위해 추가합니다.
ANSI_NULLS 라는 옵션을 대부분 알고 계실 것입니다. 대부분의 DB에서는
(G마켓의 MS-SQL SERVER 포함) ANSI_NULLS ON 으로 사용합니다.
(NULL을 본래 그대로의 뜻인 미확정값으로 사용하겠다는 의미입니다.
MS-SQL SERVER에서는 NULL을 확정값처럼 사용하도록 할 수 있습니다.
특이한 옵션인거죠? ㅎㅎ (오라클 사용하던 저로서는 마냥 신기해했던 옵션입니다)
그렇다면..
SET ANSI_NULLS OFF 로 해주고 위의 쿼리를 다시 돌려보면 결과가 어떻게 나올까요?
............ 한 10초쯤 생각해 보시기 바랍니다. ...........................
예상하셨다시피 NULL 값을 확정값처럼 DB에서 생각하기 때문에
위의 두 쿼리는 아래처럼 같은 비용을 내게 됩니다.
하지만, 울회사에서는 ANSI_NULLS 를 ON 으로 주고 사용하기 때문에 여러분들은 역시
SP 작성하실 때에 주의를 기울여 주시지 않으면 안된다는 겁니다. ^^
결론 : 여러분의 작은 관심이 시스템을 조금 더 안정적으로 만들 수 있습니다.
그럼 또 좋은 '꺼리' 생기면 찾아뵙겠습니다. ㅎㅎ
Posted by maceo