IS NOT NULL 조회에 대한 개선방법 찾기

  • IS NOT NULL 조회는 SQL 구성이나 컬럼의 인덱스 구성정보에 따라 많은 성능편차가 발생하는데, 최소한 IS NOT NULL 로 조회하는 컬럼을 이용한 인덱스 스캔이 효율적이라면, ISNOT NULL 조회 조건을 인덱스 스캔이 가능한 조건으로 변경할 필요가 있다.
  • IS NOTNULL 조건을 변경할 때는 컬럼의 데이터 타입에 따라 변경하는 방법이 달라지게 된다

-- CHAR[VARCHAR2]  : column > chr(0) [ or column > ' ']
-- DATE            : column > to_date('19000101','yyyymmdd')
-- NUMBER          : column >= 0 OR column <


-- char(varchar2) 타입의 컬럼의 IS NOTNULL
-- 기본적으로 is not null 은 인덱스를 사용하지 못함으로 다음과 같은 문자 타입은 
   가장 작은 보다 큰값 조회 하는 방식으로 인덱스를 탈수있다.

SQL> WITH not_null_t AS ( SELECT 'a' AS c1 FROM DUAL
  2  UNION ALL
  3  SELECT null FROM DUAL
  4  UNION ALL
  5  SELECT 'b' FROM DUAL
  6  UNION ALL
  7  SELECT '0' FROM DUAL )
  8  SELECT *
  9  FROM not_null_t
 10  WHERE c1 IS NOT NULL ;

C
-
a
b
0

SQL> WITH not_null_t AS ( SELECT 'a' AS c1 FROM DUAL
  2  UNION ALL
  3  SELECT null FROM DUAL
  4  UNION ALL
  5  SELECT 'b' FROM DUAL
  6  UNION ALL
  7  SELECT '0' FROM DUAL )SELECT *
  8  FROM not_null_t
  9  --WHERE c1 IS NOT NULL
 10  WHERE c1 > CHR(0) ;

C
-
a
b
0



-- DATE 타입의 컬럼의 IS NOTNULL

SQL> ALTER SESSION SET nls_date_format = 'yyyy-mm-dd';

Session altered.

Elapsed: 00:00:00.00
SQL> WITH not_null_t AS ( SELECT TO_DATE('20110101','yyyymmdd') AS c1 FROM DUAL
  2  UNION ALL
  3  SELECT NULL FROM DUAL
  4  UNION ALL
  5  SELECT TO_DATE('20111111','yyyymmdd') FROM DUAL )
  6  SELECT *
  7  FROM not_null_t
  8  WHERE c1 IS NOT NULL ;

C1
----------
2011-01-01
2011-11-11

Elapsed: 00:00:00.00
SQL> WITH not_null_t AS ( SELECT TO_DATE('20110101','yyyymmdd') as c1 FROM DUAL
  2  UNION ALL
  3  SELECT null FROM DUAL
  4  UNION ALL
  5  SELECT TO_DATE('20111111','yyyymmdd') FROM DUAL)
  6  SELECT *
  7  FROM not_null_t
  8  WHERE c1 > TO_DATE('19000101','yyyymmdd'); -- C1 컬럼에 존재할 수 없는 이전 값
 




-- Number 타입의 컬럼에 IS NOT NULL

-- NUMBER 타입인 컬럼의 IS NOT NULL 조회는 0 을 기점으로 하여 모든 데이터를 추출하도록 조건을 변경하면 된다.

SQL> WITH t1 AS ( SELECT -1 AS c1 FROM DUAL
  2  UNION ALL
  3  SELECT NULL FROM DUAL
  4  UNION ALL
  5  SELECT 1 FROM DUAL
  6  UNION ALL
  7  SELECT 1.2 FROM DUAL
  8  UNION ALL
  9  SELECT 0 FROM DUAL)
 10  SELECT *
 11  FROM t1
 12  WHERE c1 IS NOT NULL
 13  ;

        C1
----------
        -1
         1
       1.2
         0

SQL> WITH t1 AS ( SELECT -1 AS c1 FROM DUAL
  2  UNION ALL
  3  SELECT NULL FROM DUAL
  4  UNION ALL
  5  SELECT 1 FROM DUAL
  6  UNION ALL
  7  SELECT 1.2 FROM DUAL
  8  UNION ALL
  9  SELECT 0 FROM DUAL )
 10  SELECT *
 11  FROM t1
 12  WHERE c1 >= 0 OR c1 < 0 ;

        C1
----------
        -1
         1
       1.2
         0