[sqlp]/친절한SQL튜닝

IN 조건은 '=' 조건이 아닌이유 - BETWEEN, IN-List

soo- 2026. 5. 10. 18:32

1.BETWEEN을 IN-List로 바꾸면 항상 좋을까?

선두 컬럼이 BETWEEN조건이면 후행 컬럼을 인덱스에서 거를 수 없어 비효율이 발생한다고 한다.

-- 친절한SQL튜닝 책 예시
-- BETWEEN 방식
where 인터넷매물 between '1' and '3'
  and 아파트시세코드 = 'A01011350900056'
  and 평형 = '59'
  and 평형타입 = 'A'

-- IN-List 방식
where 인터넷매물 in ('1', '2', '3')
  and 아파트시세코드 = 'A01011350900056'
  and 평형 = '59'
  and 평형타입 = 'A'


BETWEEN을 IN-List로 바꾸면 옵티마이저는 IN-List Iterator 방식으로 풀면서 각 값마다 모든 컬럼을 '='조건으로 검색한다. 즉 UNION ALL을 여러개 붙인 것과 같은 방식이 된다.


2. 두 방식의 본질적인 비용은 어디서 차이가 날까?

  • BETEWEEN
    • 수평적 스캔 비용
    • 범위 안 레코드가 흩어져 있으면 리프블록을 가로질러 탐색
  • IN-List Iterator
    • 수직 탐색 비용
    • IN-List 항목마다 루트->브랜치->리프로 새로 탐색
    데이터 분포에 따른 트레이드 오프
    • 데이터가 넓게 퍼져 있음
    • BETEWWEN : 수평 스캔량이 많아짐 (불리)
    • IN-List : 수직 탐색으로 이퀄 값만을 콕 찍음 (유리)
    • 데이터가 뭉쳐 있음
    • BETEWWEN : 수평 스캔량이 적음, 리프블록을 적게 스캔 (유리)
    • IN-List : 수평 스캔량에 비해 수직 탐색량이 많게 됨 (불리)
    즉, BETEWEEN의 수평 스캔량과 IN-List의 수직 탐색량을 잘 따져봐야 한다
    인덱스 리프 블록 (8KB)에는 수백개의 레코드가 들어간다. BETWEEN으로 비효율 스캔해도 블록 I/O자체는 얼마 안될 수 있다