CREATE INDEX TB_ORD_IDX01 ON TB_ORD (ORD_DT, ORD_NM);
통계 정보
ANALYZE TABLE TB_CUST COMPUTE STATISTICS
FOR TABLE FOR ALL INDEXES FOR ALL INDEXED COLUMNS SIZE 254;
ANALYZE TABLE TB_ORD COMPUTE STATISTICS
FOR TABLE FOR ALL INDEXES FOR ALL INDEXED COLUMNS SIZE 254;
중첩 루프 조인 (테이블 풀 스캔)
SELECT /*+ LEADING(A) USE_NL(B) */
*
FROM TB_CUST A,
TB_ORD B
WHERE A.CUST_NM LIKE 'L%'
AND A.CUST_ID = B.CUST_ID
AND B.ORD_DT
BETWEEN TO_CHAR(SYSDATE - 365, 'YYYYMMDD')
AND TO_CHAR(SYSDATE, 'YYYYMMDD');
-- [2021-07-29 15:55:39] 3,678 rows retrieved starting from 1 in 9 m 40 s 31 ms (execution: 15 s 947 ms, fetching: 9 m 24 s 84 ms)
SQL 분석
LEADING 힌트를 사용하여 고객 테이블을 Outer 테이블로 설정
USE_NL 힌트를 사용하여 주문정보 테이블과 중첩 루프 조인이 이루어지도록 설정
고객테이블과 주문정보 테이블을 고객아이디 컬럼을 기준으로 '=' 조인
주문정보 테이블은 고객아이디를 선두 컬럼으로 한 인덱스가 존재하지 않으므로 주문정보 테이블은 테이블 풀 스캔으로 처리된다.
CREATE INDEX TB_CUST_IDX01 ON TB_CUST (CUST_NM);
CREATE INDEX TB_ORD_IDX02 ON TB_ORD (CUST_ID, ORD_DT);
ANALYZE INDEX TB_CUST_IDX01 COMPUTE STATISTICS;
ANALYZE INDEX TB_ORD_IDX02 COMPUTE STATISTICS;
SELECT/*+ LEADING(A) INDEX(A TB_CUST_IDX01)
USE_NL(B) INDEX(B TB_ORD_IDX02) */
*
FROM TB_CUST A,
TB_ORD B
WHERE A.CUST_NM LIKE 'L%'
AND A.CUST_ID = B.CUST_ID
AND B.ORD_DT
BETWEEN TO_CHAR(SYSDATE - 365, 'YYYYMMDD')
AND TO_CHAR(SYSDATE, 'YYYYMMDD');
-- [2021-07-29 15:56:37] 3,678 rows retrieved starting from 1 in 384 ms (execution: 19 ms, fetching: 365 ms)
SQL 분석
LEADING 힌트를 사용하여 고객 테이블을 Outer테이블로 지정
INDEX 힌트를 사용하여 고객명에 대한 인덱스를 스캔하도록 지정
USE_NL 힌트를 이용하여 중첩 루프 조인을 유도, 주문 테이블을 Inner 테이블로 지정
INDEX 힌트를 사용하여 고객아이디 + 주문일자 인덱스를 스캔
고객 테이블의 스캔 건수만큼 Inner 테이블인 주문정보 테이블을 스캔 시 효율적인 인덱스 스캔으로 성능 향상을 예상할 수 있다.