심심하기도 하고, 현업에서 조회 쿼리 느린게 있다고 연락와서 살펴 본 결과,
왼쪽 컬럼에 변형을 많이 가했고, 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로 인식하기 때문이다.