develop

IS NOT NULL 관련해서. is not null을 부정문 형태를 긍정문 형태로 바꿔 보자.

파드파드 2007. 8. 22. 11:37
반응형

심심하기도 하고, 현업에서 조회 쿼리 느린게 있다고 연락와서 살펴 본 결과,
왼쪽 컬럼에 변형을 많이 가했고, is not null이라는 부정문을 사용 했더라. 그리고 평상시는 그럭저럭
괜찮은데 사용자가 많을때 쿼리 속도는 더욱더 떨어지고 있고...
일단 정공법으로 돌진.

-- NULL TEST
SELECT *
FROM (
 SELECT NULL AS A,  '11' B FROM DUAL
 UNION ALL
 SELECT '' AS A,  '22' B FROM DUAL
 UNION ALL
 SELECT '1' AS A,  '33' B FROM DUAL
 UNION ALL
 SELECT '2' AS A,  '44' B FROM DUAL
 UNION ALL
 SELECT ' ' AS A,  '55' B FROM DUAL
) C
WHERE
--C.A = NULL -- 이런거는 없다.
--C.A = '' -- 이런거는 없다.
--C.A IS NULL -- 널은 이렇게 찾는다.
--C.A IS NOT NULL --  1. 널이 없는 것.
--C.A > ' '  --  2. 널이 없는 것. 부정문은 인덱스가 무시되므로 이처럼 변경.
--C.A = DECODE(C.A, NULL, NULL, C.A)
                  -- 3. 널이 없는 것. 부정문은 인덱스가 무시되므로 이처럼 변경.


1 은 일반적인 방법. 부정문이라서 인덱스를 못타게 되고 그래서 풀스캔의 원인.

2 는 어디선가 봤던 방법.  컬럼의 데이타타입이 date일 경우는 사용못한다.(사용을 못한다기
보다는 컬럼 변형을 해야한다.) 수정해야할 쿼리가 이러하다.
하여간 그래서 3번째 방법을 만들었다.

3 은 C.A = null 이런 표현식은 결과가 없을 것이다. 그래서 no row가 발생하고,
나머지는 c.a = c.a 이니 널이 아닌 데이타만 나온다.
하지만 보기에도 뭐가 좀 복잡해 보인다. 그렇다 복잡하다.

흠,
튜닝은 그때 그때 마다 다르다가 결론!


=================================================================================

그런데 MS SQL에서는?

-- NULL TEST
SELECT *
FROM (
 SELECT NULL AS A,  '11' B
 UNION ALL
 SELECT '' AS A,  '22' B
 UNION ALL
 SELECT '1' AS A,  '33' B
 UNION ALL
 SELECT '2' AS A,  '44' B
 UNION ALL
 SELECT ' ' AS A,  '55' B  
 UNION ALL
 SELECT '  ' AS A,  '66' B  
) C
WHERE
--C.A = NULL -- a
C.A = '' -- b
--C.A IS NULL -- c
--C.A IS NOT NULL -- d
--C.A = CASE C.A WHEN NULL THEN NULL ELSE C.A END -- e
--C.A > ' '  -- f

b와 f의 경우에만 오라클과 다르다. 오라클은 '' = null로 인식하고,
ms sql은 '' 을 blank로 인식하기 때문이다.

반응형