IN 조건이 '=' 조건이 아닌 이유 - 인덱스 컬럼 순서
같은 IN 조건이라도 인덱스를 어떻게 구성하느냐에 따라 동작 방식과 비용이 완전히 달라진다
--책 예시
select * from 고객별가입상품
where 고객번호 = :cust_no
and 상품ID in ('NH00037', 'NH00041', 'NH00050')
고객별 평균 카디널리티가 3이라고 가정
Case 1: 「상품ID + 고객번호」 인덱스
[리프 블록 A] [리프 블록 B] [리프 블록 C]
NH00037, 1230 NH00041, 1100 NH00050, 1234
NH00037, 1234 ← NH00041, 1234 ← ...
NH00037, 1240 NH00041, 1500
고객 1234의 엔트리가 세 개의 리프 블록에 흩어져 있다. 이때는 IN-List Iterator로 풀어야만 한다
-- 옵티마이저가 이렇게 변환
select * where 고객번호=:cust_no and 상품ID='NH00037'
union all
select * where 고객번호=:cust_no and 상품ID='NH00041'
union all
select * where 고객번호=:cust_no and 상품ID='NH00050'
수직 탐색 3번 × 3블록 = 총 9개 블록 I/O
Case 2: 「고객번호 + 상품ID」 인덱스
[리프 블록]
1234, NH00037 ← 필요
1234, NH00041 ← 필요
1234, NH00050 ← 필요
1234, NH00099 ← 필터로 제외
1235, NH00012
고객 1234의 엔트리가 한 블록에 모여 있다. 이때는 IN-List Iterator로 풀 필요가 없다.
- 고객번호=1234만 액세스 조건으로 사용
- 상품ID는 필터로 처리
- 수직 탐색 1번(3블록) + 리프 1
2블록 = 총 45개 블록 I/O - IN 조건이 '=' 조건이 되려면
IN-List Iterator 방식으로 풀려야만 IN 조건이 '=' 조건이 된다. 그렇지 않으면 IN 조건은 필터 조건이다.
'[sqlp] > 친절한SQL튜닝' 카테고리의 다른 글
| IN 조건은 '=' 조건이 아닌이유 - BETWEEN, IN-List (0) | 2026.05.10 |
|---|---|
| 인덱스 스캔과 동작원리 (0) | 2026.05.09 |