일단 문제는 https://gall.dcinside.com/mgallery/board/view/?id=backend&no=20979 이 문제고


정답은
SELECT*
FROM 고객
WHERE 가입일자 Between '201001' and '201012'
AND 고객 등급  In ('A', 'B') 임 

가볍게 설명하자면 Between 부분을 -> IN 
Like 부분을 -> Between 방식으로 바꿔야함 

내가 설명하고 싶은 부분은 Like임(나도 Like를 쓰면 안된다~만 기억나서 책보고 다시 공부함)


CASE1) WHERE 고객등급 = 'B' And 가입일자 Like '2010%' vs WHERE 고객등급='B' 가입일자 Between '201001' and '201012' 는 서로 다름


결과적으로 데이터는 같겠지만 인덱스 스캔량이 차이가 날수 있음.(무조건 차이가 나는거는 아님)


만약 데이터 분포가 그림 3-41와 같이 되어있으면(날짜는 좀 틀린데 이정도는 이해할거라 믿음) Like는 '201000'도 저장돼 있을 수 있기 때문에 B부터 바로 읽을 수 없음

반면 Between은 효율적으로 읽을 수 있음 고객등급 A를 읽는 케이스도 있음

CASE2) WHERE 고객등급 = 'A' And 가입일자 Like '2010%' vs WHERE 고객등급='A' 가입일자 Between '201001' and '201012' 도 서로 다름


이것도 위와 동일하게 Between 쿼리는 스캔 종료 시점이  'B'인 첫 레코드에서 바로 종료할 수 있는데 Like 쿼리는 201013이 있을까봐 고객등급 'B'인 데이터까지 전부 다 스캔 후 종료할 수 있음


이 와 같은 사례때문에 날짜는 Between 쿼리를 사용하는게 좋음(가독성 측면에서도 더 좋고)


Q: Like는 내부적으로 캐스팅이 일어나기 인덱스를 못타는거 아니냐?
A: DBMS 마다 다름 어떤 디비는 암묵적으로 캐스팅하고 어떤 디비는 명시적으로 캐스팅 해야 하는 디비가 있음 근데 위의 문제는 오라클 기준으로 인덱스를 탈수있음

오라클 기준으로 문자열 vs 숫자형이 만나면 숫자형이 이기고 문자열 vs 날짜형이 날짜형이 이김 따라서 위에서 조건절 문자열이 -> 날짜형으로 캐스팅 되기 때문에

인덱스를 탈수있음