본문 바로가기

DB

내 쿼리에 Index 고속버스를 꼭 태우자! (Oracle)

● INDEX를 사용하지 않은 경우
   (다음의 4가지 경우엔 Index를 사용하지 않게 때문에 주의해서 사용해야 함.)

        ▷ INDEX COLUMN의 변형
           ex) 외부적 변형
               SELECT *
             FROM DEPT
            WHERE SUBSTR(DNAME, 1, 3)  =  'ABC'
            
       개선 => SELECT *
                 FROM DEPT
                WHERE DNAME LIKE 'ABC'||'%'

           ex) 내부적 변형
               SELECT *
             FROM DEPT
            WHERE JOB  =  12 (※ job은 Varchar2로 생성된 경우 내부적으로 char -> int로 형변환이 일어남 : INT(JOB))
            
       개선 => SELECT *
                 FROM DEPT
                WHERE JOB = '12'
       ※ 숫자는 형을 정확히 모를 경우에는 무조건 ''로 묶어 주는것이 좋음
          만약 job이 Number형인 경우 내부적으로 int('12') 가 진행됨.

        ▷ NOT Operator            
           ex) SELECT *
             FROM EMP
            WHERE JOB <> '01'
            
       개선 =>         SELECT *
                  FROM EMP
                 WHERE JOB IN ('02', '03', '04', '05')  
       ※ NOT 이외의 모든 코드값을 넣어 준다.(모든 코드값을 아는 경우에 한함)

        ▷ NOT NULL                      
           ex) SELECT *
             FROM DEPT
            WHERE JOB IS NOT NULL
      
       개선1 => SELECT *
                  FROM DEPT
                 WHERE JOB >= ''
      
       개선2 => SELECT *
                  FROM JOB A
                 WHERE NOT EXISTS ( SELECT 'X'
                                      FROM JOB B
                                     WHERE A.JOB_CODE = B.JOB_CODE )
        ※ NOT EXISTS 를 이용하여 개선
           - NOT EXISTS는 부분범위 Index를 탈 수 있기 때문에 가능하면 개선하여 처리

        ▷ Optimizer의 취사 선택                
           ex) SELECT *
             FROM DEPT
            WHERE JOB  LIKE 'AB%'
              AND EMPNO  =  '7890'
           ※ 기본적으로 "="조건인 empno index를 먼저 탄다.
              하지만 job index를 먼저 태우고 싶은 경우 empno index를 타지 못하게 칼럼을 가공한다.  
              
       개선 =>         SELECT *
                  FROM DEPT
                 WHERE JOB LIKE 'AB%'
                   AND EMPNO || '' = '7890'
           ※ EMPNO에 ''을 붙여 가공함으로써 INDEX를 타지 못함.