힌트에 대해 질문드립니다. 0 11 1,076

by 사비타 [SQL Query] [2016.11.26 12:52:54]


test05라는 테이블에 ymd라는 컬럼이 있고 PK입니다.

여기에 데이터가

19961231
19970630
19971231
19980331
19980630

이런식으로 들어있습니다.

여기서 INDEX_DESC(TEST05 TEST05_PK) 이렇게 힌트를 주었을때

19980630이 나와야 되는거 아닌가요?

힌트가 걸리지 않고 계속 힌트걸기전과 똑같이 나오네요..

 ========================================================

select a.ymd, b.ymd, a.us_amount, a.us_amount * b.exc_rate

from test05 b, test04 a,

where b.ymd = (select /*+ INDEX_DESC(test05 test05_pk) */ ymd

                         from test05 where ymd < a.ymd and rownum = 1)

인덱스가 안먹네요..

by 마농 [2016.11.28 08:55:24]

사용하신 전체 쿼리를 올려주세요.

인덱스명 확인해 주세요.


by 사비타 [2016.11.28 12:59:05]

올렸습니다. 인덱스명은 확인했습니다.


by 우리집아찌 [2016.11.28 08:59:47]
인덱스를 역순으로 주신거 아닌가요??

by 마농 [2016.11.28 13:09:40]

쿼리가 이상하게 작성하셨네요.
쿼리도 전체를 다 올린게 아닌 듯 하구요.
여러 테이블이 등장하네요.
의도에 맞게 작성된 쿼리가 아닐것 같네요.
단순 인덱스 문제로 질문할 상황이 아닌것 같아요.
의도하는 바가 뭔지? 의도하는 바를 구하는 쿼리를 어떻게 작성하는지? 를 질문하셔야 할 듯.


by 마농 [2016.11.28 16:09:53]

비슷한 쿼리를 만들어 테스트해봤습니다.

정상적으로 인덱스 타서 결과가 나오네요.

그런데 굳이 힌트 안쓰고 MAX 로 구하는게 여러모로 더 좋습니다.

MAX 를 쓰면 (INDEX_DESC + ROWNUM) 과 동일한 성능이 나오며, 오류의 가능성은 없습니다.

SELECT a.deptno aa
     , b.deptno bb
  FROM dept b
     , dept a
 WHERE b.deptno = (SELECT /*+ INDEX_DESC(dept pk_dept) */ deptno
                     FROM dept
                    WHERE deptno < a.deptno
                      AND ROWNUM = 1
                   )
;
-- 결과 --
AA  BB
--  --
20 10
30 20
40 30

 


by 사비타 [2016.11.28 16:33:19]

by 사비타 [2016.11.28 16:36:28]

제가 설명이 부실했던거 같네요.

현재 책으로 학습하고 있는데요. (책은 오라클실습/저자:이채남)

특정컬럼의 값을 기준으로 현재 행보다 작은값을 가진 행중 최대값을 읽어오는 예제입니다.

위 쿼리는 책에 있는답을 그대로 가져온거구요. 아래쪽 IN 조건은 없어도 무방해서 뺐었어요.

근데 저렇게 해도 인덱스가 먹지 않는거같아서 이유가 먼가 싶어서 질문을 해봤습니다.

 


by 사비타 [2016.11.28 16:39:31]

지금 다시 쳐보니까 제대로 나오네요;; 제가 먼가 잘못쳤나보네요.

근데 책에서는 HINT를 사용하는게 제일 효과적인 방법이라고 하는데 이 책이 옛날책이거든요.

요즘에는 max가 제일 좋은방법인가요?


by jkson [2016.11.28 17:11:36]

이 글 읽어보세요.

http://scidb.tistory.com/entry/Indexdesc-%ED%9E%8C%ED%8A%B8%EC%99%80-rownum-1-%EC%A1%B0%ED%95%A9%EC%9D%80-%EC%95%88%EC%A0%84%ED%95%9C%EA%B0%80

hint + rownum 이 약간 위험한 방법이죠. index에 이상 생긴다든지 하면 완전 엉뚱한 결과를 가져오기 땜시롱.. 선두 컬럼 조건 없을 때 상황에 대한 내용 때문에 글이 긴데.. max/min 사용하라는 말입니다. 물론 실행계획을 확인하셔서 first_row 로 잘 되는지 확인하셔야겠죠.


by 마농 [2016.11.28 17:21:55]

인덱스 항목에 대한 MIN/MAX 처리는 이미 최적화 되어 있습니다.
  - 인덱스 1건만 읽고 멈추죠.
INDEX_DESC 힌트 + ROWNUM = 1 의 경우
  - 정상동작한다면? 마찬가지로 최적화된 답일 수 있습니다.
  - 그러나 비정상 동작할 가능성에 대해 여러 책에서 언급하고 있는데요.
  - 테이블을 관리하다보면 인덱스 명칭이 바뀔수도 있다는 거죠.
  - 인덱스 명이 바뀌거나 인덱스 자체가 삭제되거나 한다면? 힌트는 무효화되고 비정상동작을 하게 됩니다.
인덱스가 없다면?
  - (INDEX 힌트 + ROWNUM)은 부정확한 결과를 빠르게 리턴합니다.
  - MIN/MAX 는 전체 스캔후 느리지만 정확한 결과를 반환합니다.
  - 즉 인덱스가 있으면 동일한 성능을 내고
  - 인덱스가 없으면 정확한 결과를 내는 MIN/MAX 를 선호해야 하겠지요.


by 사비타 [2016.11.28 18:02:45]

좋은 설명 감사드립니다.

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