index 현상에 대해서 문의드립니다. 0 7 2,066

by 강서꽃미남 [2015.03.03 19:50:35]


안녕하세요. 3월이 지나가고 있습니다. 비도 추적추적 내리네요.

다들 잘지내시죠?

오늘 있었던 이슈인데요 평상시 제가 SQL을 잘 못하는데... 이해 못하는 부분이 발생되서요.

본문으로 들어가서 쿼리는 아래와 같습니다. 추후는 생략했어요.

 

SELECT /*+ INDEX_DESC(A SYS_C00207718) */
      ROWNUM RN,
       A.SEQ,
       A.TITLE,
       A.HIT,
       A.INSERTED_BY,
       A.INSERTED_DATE,
       B.NAME
  FROM BOARD A, CUSTOMER B
 WHERE A.INSERTED_BY = B.LOGIN_ID

SYS_C00207718는 BO_BOARD (SEQ)의 유니크 인덱스 이자 pk입니다.

 

B와 조인하지 않을 경우 SEQ별로 제대로 INDEX DESC가 수행됩니다.

그런데 조인할 경우 SEQ가 뒤죽박죽이 되어버리더라구요. 재현 해보려고 하니 제가 테스트하며 결합인덱스로 그냥 묶어버리고 where 조건을 결합인덱스에 해당하는 조건으로 주니 해결되버려서 플랜을 재현할 수가 없는데요..

위와 같이 구현할 경우 문제가 발생하기도 하나요? (혹시 ROWNUM과 JOIN의 순서로 인한 문제인가요?)

처음엔 ROWNUM 관련 에러인지 알았는데 조인만 제거하면 정상으로 답이 나와서요.

이 부분에 대해서 궁금합니다. 혹시 페이징 처리할 때 어떻게 구현하시나요?

--

참고로 플랜은 CUSTOMER FULL SCAN 후 INDEX(UNIQUE) 그리고 네스티드 루프  ROW ID 네스티드 루프 순으로 풀렸습니다.

by DarkBee [2015.03.03 21:07:17]

for문을 board 부터 돌려야 순서가 보장되지 for문을 customer 부터 돌려봐야 건바이건 조인밖에 더하나..

/*+ ordered use_nl ( a b ) */

 

잡담.

11g 부턴 nested loop join 일시 인덱스를 지정해도 순서를 보장하지 않는다고 어디서 본거같은데..


by 강서꽃미남 [2015.03.04 09:27:26]

감사합니다. use_nl 으로 하니 해결은 했었거든요.. 명시적으로 줘야하는게 맞는거군요.


by 마농 [2015.03.04 08:58:18]

1. b 를 먼저 읽고 a 를 읽는 경우
  - 이 경우 a.seq 인덱스는 타지 않습니다.
2. Hash Join 이 발생된 경우
  - a.seq 인덱스를 Desc 로 정상적으로 읽었어도
  - NL Join 이 읽어나지 않는다면 정렬은 깨지게 됩니다.
3. a.seq 인덱스를 Desc 로 타고 NL Join 이 발생하더라도
  - 11G NL 조인에서는 batch I/O 매카니즘으로 정렬 순서가 보장되지 않습니다.


by 강서꽃미남 [2015.03.04 09:27:54]

감사합니다!!! 하나 알고가네요...ㅎㅎ

지금보니 인덱스는 타지만 해쉬조인이 일어나는 경우네요. 2번째 경우에요.

감사합니다.


by 마농 [2015.03.04 09:39:02]

Ordered Use_NL 힌트로 제어를 하더라도
결국 Order By 구문을 마지막에 필수로 넣어주셔야 합니다.
Order By 구문을 넣는다고 수행속도가 저하되는게 아닙니다.
인덱스를 이용해 순서가 보장된다면 별도의 정렬작업이 수행되지 않으며 속도에 영향이 없습니다.
또한 인덱스를 이용하지 못해 순서가 보장되지 않더라도 정렬작업을 수행해 결과를 보장합니다.


by 마농 [2015.03.04 09:46:35]
-- 스칼라서브쿼리를 이용해 조인으로 인한 순서변경을 방지하는 방법도 있겠네요.
SELECT /*+ INDEX_DESC(a sys_c00207718) */
       ROWNUM rn
     , a.seq
     , a.title
     , a.hit
     , a.inserted_by
     , a.inserted_date
     , (SELECT b.name FROM customer b WHERE b.login_id = a.inserted_by) name
  FROM board a
 ORDER BY a.seq DESC
;

 


by 강서꽃미남 [2015.03.04 09:58:41]

이런방법도 있군요.. 네 order by를 추가해줬습니다.

완전 감사합니다.!!!

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