단일 인덱스에 대한 = 과 LIKE 1 7 1,822

by 야신 [Oracle 기초] [2013.10.31 09:48:57]


품목 테이블에
item_name 과 item_id 두개가 유니크인덱스로 잡혀 있는데

item_name like 'AAA' ( index range scan )

item_name = 'AAA' ( index unique scan )

이 인덱스를 다르게 타고 후보 개수는 같아도 cost 와 io 가 like 를 쓴것이 약간 더 증가하네요.
오라클이 알아서 like 를 써도 % 를 안 붙였으니 unique scan 을 타기를 바란것은 무리였나 봅니다.

또한 통계 정보에 따라 ID 를 가진 인덱스를 타서 엄청나게 시간이 오래 걸려버리기도 하네요 ㅠㅠ

혹시 무의식적으로 like 를 쓰시는 분들이 있으면 검토해 보셨으면 해서 올려요.

by 우리집아찌 [2013.10.31 09:55:18]

흠.. 초보때에는 LIKE 무한사용을 즐겼는데.. 잘못되었군요..

by 야신 [2013.10.31 10:52:00]
전 초보가 아닌데도 가끔 저렇게 ...ㅡㅡ;;

by 우리집아찌 [2013.10.31 11:15:51]
지금은 ibatis가 동적쿼리지원되니까 편하게 쓰고있습니다.

by 마농 [2013.10.31 10:19:41]

아이템 검색시 보통 다음과 같이 하죠.
   AND item_name LIKE :v_item_name || '%'
위에 말씀하신 경우는 전체 검색시에 널대신 아예 '%'를 넘기는 형태인 듯 하네요.
   AND item_name LIKE :v_item_name
v_item_name 에 값이 입력되지 않으면 전체검색을 하게 하기 위함이죠.
이 경우 실행계획이 한쪽으로만 고정되겠지요 ( index range scan )
다음과 같이 바꾸시면 두가지 실행계획으로 분리가 됩니다.
   AND item_name = DECODE(:v_item_name, '', item_name, :v_item_name)
- 조건이 입력되면 : ( index unique scan )
- 조건이 입력되지 않으면 : ( table full scan ) 또는 ( index full scan )


by 우리집아찌 [2013.10.31 10:41:18]
오.. 좋은 방법입니다.

by 야신 [2013.10.31 10:50:10]
오~ 그런 방법이 있군요.
거기까지 생각을 못했는데...
감사합니다.

by jkson [2017.01.19 19:53:43]

이렇게 사용시려면 item_name 컬럼이 null이 아니어야한다는 전제가 붙습니다. 조건이 입력 안 되었을 때 null일 경우 item_name = item_name 조건이 성립이 되지 않기 때문에 결과에서 누락됩니다. 마농님도 알고 계셨겠지만 댓글에 적는 걸 깜빡하신듯 하네요.

과거 글이지만 혹시나 저처럼 검색하다가 보시는 분이 계실까봐 댓글 달아놓습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입