핵심만 다시 풀어볼게요.
인덱스 상품_X01은 (상품ID + 상품구분코드) 순서입니다. 쿼리는 상품ID = :prod_id (등치) AND 상품구분코드 IN ('GX','KR') 이고, 실행계획을 보면 상품ID는 access, 상품구분코드는 filter로 처리됐어요. IN 조건이 OR로 풀렸는데도 access가 아니라 filter로 남은 거죠.
왜 그런가 하면, 상품ID가 Unique합니다. 즉 상품ID = :prod_id 조건만으로도 이미 딱 1건이 좁혀져요. 이 상태에서 상품구분코드의 IN 조건까지 access로 만들겠다고 IN-List Iterator를 쓰면, 'GX'일 때 한 번, 'KR'일 때 한 번 — 인덱스를 두 번 따로 스캔하게 됩니다. 그런데 어차피 상품ID로 1건만 찾으면 끝나는 일을, 두 번 스캔해서 나눠봐야 얻는 게 없어요. 오히려 두 번 스캔하는 오버헤드만 생기죠. 그래서 책에서 "IN-List Iterator로 유도하면 도움이 될까? X01을 (상품구분코드+상품ID)로 바꾸면 도움이 될까?"라고 묻고 — 둘 다 도움 안 된다고 답하는 거예요.
정리하면, 후행 컬럼의 IN 조건을 access로 바꾸는 전략이 유리한지는 "선행 컬럼의 access 조건이 이미 얼마나 좁혀주는가"에 달려 있습니다. 선행 컬럼이 Unique하거나 매우 좁게 걸러주면, 후행 IN은 그냥 filter로 둬도 됩니다(좁혀진 한두 건 안에서 체크하면 그만이니까). 반대로 선행 컬럼이 많은 행을 남긴다면, 후행 IN을 IN-List Iterator로 access화하는 게 진짜 도움이 됩니다.
어느 부분이 아직 막히세요? "선행 조건이 좁혀준다"는 감이 안 잡히시는지, 아니면 IN-List Iterator 자체의 동작이 헷갈리시는지요?