1. 표현식, 함수, 계산식을 인덱스 컬럼에 사용하면 인덱스 사용은 불가능하다.
Upper함수를 걸었을 때 인덱스를 못하고 Full 스캔한다.
2020-07-23 오전 10:07 - 화면 캡처
함수를 제거하고 그냥 돌리면 인덱스 스캔을 하게 된다.
2020-07-23 오전 10:08 - 화면 캡처
따라서 컬럼 자체에 함수를 걸지 말고 컬럼은 그대로 두고 조건식에서 맞춰줘야 성능이 더 좋다
즉, 이렇게 인덱스컬럼에 함수를 걸어 주지 말고
2020-07-23 오전 10:10 - 화면 캡처
인덱스 컬럼을 그대로 두고 식으로 같은 결과를 뽑을 수 있게 짜야 한다.
2020-07-23 오전 10:11 - 화면 캡처
2. WHERE 절에서 인덱스컬럼의 데이터 타입과 일치해서 식을 만들어라.
VARCHAR2 타입의 DEPTNO를 NUMBER로 검색을 했다.
즉, 오라클에서 자동으로 where TO_NUMBER(DEPTNO) = 1; 로 변환시키며
인덱스 컬럼에 함수가 씌워진 것이다. 그럼 모다? 풀 스캔을 하게 된다.
2020-07-23 오전 10:12 - 화면 캡처
하지만 인덱스 컬럼의 데이터 타입과 일치하게 식을 만들어주면 이렇게 인덱스를 잘 타게된다.
2020-07-23 오전 10:15 - 화면 캡처
3. IN을 이용한 조인보다는 EXISTS 를 이용해서 짜라.
1. 매커니즘
EXISTS : 조건에 해당하는 ROW의 존재 유무와 체크 후 더 이상 수행하지 않음.
IN : 조건에 해당하는 ROW의 칼럼을 비교하여 체크한다.
즉, Exists는 값이 존재하는지만 체크하는 것이고
IN은 그 존재한 값을 다시 컬럼과 비교하는 것이다. 따라서 IN은 2중으로 체크를 하는 것 같다.
2. 실행순서
EXISTS는 메인 쿼리의 결과값을 서브 쿼리에 대입하여 조건 비교 후 결과를 출력
IN은 서브쿼리의 결과값을 메인 쿼리에 대입하여 조건 비교 후 결과 출력
3. 실습
IN으로 돌렸을때 서브쿼리의 myemp1 을 풀스캔하면서 2의 비용이 발생하고 이걸 sort하는데 또 2의비용 발생, 그리고 인덱스를 탄 메인쿼리와 비교를 하게 된다. 총 4의 비용이 발생
2020-07-23 오전 10:24 - 화면 캡처
EXISTS로 돌렸을 때를 봐보자.
Exists절은 where 절에 별도의 인덱스 컬럼 명시 같은걸 하지 않기 때문에 메인 쿼리의 myemp1을 풀스캔하게 된다.
그리고 서브쿼리절의 테이블을 스캔하지 않고 값의 존재유무만 곧바로 따지게 되는 것 같다.(뇌피셜)
2020-07-23 오전 10:26 - 화면 캡처
즉, IN은 모든 값까지 확인하고 체크하기 떄문에 메인 쿼리 테이블과 서브 쿼리 테이블을 다 스캔한 후 각각의 값을 비교하는 작업을 거치는 것 같고,
EXISTS는 단지 ROW가 존재 하는지만 체크하기 때문에, 메인 쿼리 테이블을 다 스캔한 후 서브쿼리의 존재여부만 따지는 것 같다. 따라서 서브쿼리쪽 존재유무만 체크하기 때문에 오라클 실행계획에 별도의 서브쿼리 테이블에 대한 스캔을 하지 않는 것 같다.
댓글