동일한 쿼리라도 인덱스 생성 포인트에 따라서 테이블 접근 방향은 가변적이다.
따라서 최소한의 코스트가 소요되는 접근 방향을 결정하고 그에 따른 필요한 위치에 인덱스를 생성한다면, 옵티마이저도 우리와 동일한 판단(플랜)을 할 것이다. 하지만 우리가 접한느 대부분의 경우는 이처럼 단순하지는 않다.
위의 그림처럼 1번, 2번, 3번, 4번 모든 컬럼 위치에 인덱스가 존재한다면 테이블의 접근 순서는 명확하지 않다. 고객->주문 방향으로 접근도 가능하고 주문->고객 방향으로 접근도 가능하다.
양 방향 접근이 가능한 것이다.
물론 옵티마이저는 수집한 통계정보에 근거하여 가장 최소한의 노력이 드는 방향을 결정하려 할 것이다. 하지만 항상 올바른 결정만 하는 것은 아니다. 만약 우리가 판단하는 접근 방향과 옵티마이저가 판단하는 접근 방향이 다르다면, 우리는 힌트절을 통해 테이블 접근 방향을 변경할 수 있다. ORDERED 힌트절은 FROM절에 나열된 테이블 순서대로 접근하고자 할 때 사용한다.
SELECT /*+ ORDERED */
columns…
FROM 고객 A, 주문 B
WHERE A.고객번호 = B.고객번호
AND A.고객명 = ?
AND B.주문일자 = ?
위 쿼리에서 사용한 ORDERED 힌트절로 인하여 옵티마어지는 고객->주문 방향으로 접근을 진행할 것이다. FROM 절에 접근 순서대로 테이블을 나열하는 것이 중요하다. 이는 개발자 간에 테이블 접근 순서를 명시적으로 공유하는 방법이자, 오라클 옵티마이저의 잘못된 접근 순서를 ORDERED 힌트절을 사용해 바로잡기에 용이하다.
ORDERED 힌트절은 FROM 절에 나열된 테이블 순으로 접근을 유도하지만, LEADING 힌트절은 테이블 접근 순서를 명시적으로 표시할 수 있다. ORDERED 힌트절보다 훨씬 개선된 힌트절이다.
LEADING 힌트절은 FROM절에 종속적이지 않다.
SELECT /*+ LEADING(B A) */
columns…
FROM 고객 A, 주문 B
WHERE A.고객번호 = B.고객번호
AND A.고객명 = ?
AND B.주문일자 = ?
위의 쿼리에서 사용한 LEADING(B A) 힌트절로 인해 주문->고객 방향으로 접근을 진행할 것이다.
위의 그림에서 접근 경로는 12가지다.
접근 방향에 맞는 인덱스가 잘 생성되어 있고 최신의 통계정보를 갖고 있다면, 옵티마이저가 잘못된 플랜을 제시할 가능성은 낮다.
하지만 접근 경로에 대한 경우의 수가 많다면 옵티마이저가 잘못된 플랜)을 제시할 가능성도 존재한다.
만약 그러한 상황이 발생한다면 LEADING 힌트절을 통해 접근 순서를 변경하면 된다.
접근 순서에 대한 판단과 최종 결정은 사람이 한다.
*테이블 접근 순서에 대한 결정 기준으로 다음 3가지 사실
1. 진입형 테이블을 결정한다. -> 조건 중에서 조회 범위가 작은 테이블을 우선시
2. 연결 확장형보다는 연결 축소형 테이블을 우선한다. -> 조회 범위 줄어드는 JOIN을 우선한다.
3. OUTER JOIN 보다는 INNER JOIN을 우선한다. -> INNER JOIN은 조회 범위 축소 가능
'DBA' 카테고리의 다른 글
MySQL8 - Semi Join 과 Anti Join - 안티조인 세미조인 (1) | 2024.09.12 |
---|---|
DBMS_XPLAN.DISPLAY_CURSOR 결과 보는 법 (0) | 2024.09.12 |
[TIL] MySQL Hint (0) | 2024.09.12 |
인라인뷰 그리고 페이징 (1) | 2024.09.12 |
[SQLP] SQLP 44회 실기 풀이 (0) | 2024.09.12 |
댓글