728x90

aegispro님 | 튜닝 | 2013-10-05 02:00:48


테이블 디자인은 아래와 같구요. (밑줄이 primary keys입니다.)
ET_STAT_DTL_TB (ET_NUMET_STAT_SEQ_NUM, ET_STAT_TS, ET_STAGE_CD, ET_STAT_CD, ET_RSN_CD, ET_ASGN_USER_ID_NUM)

원하는 결과는 ET_STAGE_CD별로 Count를 얻고 싶어요
카운드 코드
100      01
88        02
99        03
등등등..

(1) SELECT COUNT(ET_STAGE_CD), ET_STAGE_CD

FROM (
        SELECT DTL.ET_NUM, DTL.ET_STAGE_CD, DTL.ET_STAT_SEQ_NUM, 
        ROW_NUMBER() OVER(PARTITION BY DTL.ET_NUM, DTL.ET_STAGE_CD  ORDER BY                   
        DTL.ET_STAT_SEQ_NUM  DESC) ROWNUM 
        FROM SCHEMA.ET_STAT_DTL_TB DTL 
) X WHERE  ROWNUM = 1 
GROUP BY ET_STAGE_CD

(2) SELECT
COUNT(STAT.ET_STAT_CD), STAT.ET_STAGE_CD
FROM SCHEMA.ET_STAT_DTL_TB STAT
WHERE STAT.ET_STAT_SEQ_NUM =
(
   SELECT
  MAX(STAT_TMP.ET_STAT_SEQ_NUM)
  FROM NCAPRPRD.ET_STAT_DTL_TB STAT_TMP
  WHERE STAT_TMP.ET_NUM = STAT.ET_NUM     
)
GROUP BY STAT.ET_STAGE_CD WITH UR

 
첫번째 질문은 
(1)과 (2)중에서 어느쪽이 성능면에서 더 유리한지요 ? 아니면 별 차이가 없는 지요?

두번째 질문은
(1)과 (2)의 결과물이 다르게 나오는 데...(1) 혹은 (2) 쿼리에 어떠 오류가 있는 지 전문가 분들의 의견을 듣고 싶습니다




pajama 2013-10-06 22:52:37
인덱스나 레코드수 등에 따라 차이는 있겠지만 두번째는 조인이 발생하기 때문에 비용발생이 커질 여지가 있습니다. 실행계획을 보는 것이 확실합니다. 그리고 두번째 쿼리문이 COUNT값이 ET_STAT_CD 컬럼으로 쓰셨는데 ET_STAGE_CD 컬럼을 잘못 쓰신건가요?

aegispro 2013-10-07 11:54:20
예 지적하신대로 ET_STAGE_CD가 맞아요. 제가 잘 이해가 가지 않는 부분은 (1)과 (2)의 결과가 조금 다르다는 것입니다. 
제가 무엇인가를 잘못 이해하고 있는 것인지 ... 몇시간째 고민하고 있는 데 답이 나오지 않아서요. (1)은 정확한 결과를 리턴해 주는 데 (2)는 특정 ET_NUM에 대해서는 아예 blank로 결과값이 나타납니다. 혹시 이부분 
WHERE STAT.ET_STAT_SEQ_NUM =
(
SELECT
MAX(STAT_TMP.ET_STAT_SEQ_NUM)
생략...
에서 문제가 발생할 여지가 있는 지요?

pajama 2013-10-07 17:20:59
죄송합니다. 말씀하신 내용이 좀 헷갈려서요.
결과값이 blank라는 말씀이 max함수값이 null 값이라는 말씀이신가요?

SELECT
MAX(STAT_TMP.ET_STAT_SEQ_NUM)
FROM NCAPRPRD.ET_STAT_DTL_TB STAT_TMP
WHERE STAT_TMP.ET_NUM = STAT.ET_NUM 

max값이 null이라면 테이블 조인 결과세트, 또는 특정 ET_NUM에 해당하는 결과세트가 없다는 의미입니다. (건수 0)

그리고 NCAPRPRD.ET_STAT_DTL_TB 테이블이 SCHEMA.ET_STAT_DTL_TB STAT 테이블과 동일한 테이블인가요?

aegispro 2013-10-07 21:11:12
(1) 예 동일한 테이블 맞아요 그러니까 셀프 Join입니다.
(2) 특정 ET_NUM의 결과가 다를 수 있을 까요 (위 두개의 다른 쿼리가요? 그러니까 Partition BY를 쓰는 것과 사용하지 않는 것)

pajama 2013-10-08 00:18:14
테스트로 데이터를 만들어서 해보았습니다 테이블 데이터타입이나 값은 무작위로 넣었습니다.
우선 첫번째 쿼리에서 PARTITION BY 절에서 ET_NUM과 ET_STAGE_CD 컬럼을 기준으로 정렬을 하셨는데요
서브쿼리에서 조인할때는 ET_NUM 컬럼으로만 조인해서 결과값이 다른 것으로 보입니다.

SELECT
COUNT(STAT.ET_STAGE_CD), STAT.ET_STAGE_CD
FROM SCHEMA.ET_STAT_DTL_TB STAT
WHERE STAT.ET_STAT_SEQ_NUM =
(
SELECT
MAX(STAT_TMP.ET_STAT_SEQ_NUM)
FROM NCAPRPRD.ET_STAT_DTL_TB STAT_TMP
WHERE STAT_TMP.ET_NUM = STAT.ET_NUM
AND STAT_TMP.ET_STAGE_CD = STAT.ET_STAGE_CD
)
GROUP BY STAT.ET_STAGE_CD WITH UR

제가 테스트한 결과로는 이렇게 했을때 동일한 결과가 나왔습니다.

aegispro 2013-10-08 02:12:15
아하 그렇군요. 정확하게 잘못을 지적해 주셨네요. 더 나은 대안이 없다면 성능 문제 때문에 첫번째 쿼리로 가야 할 것 같습니다. 혹시 더 나은 방법을 알고 계시는 지요?

pajama 2013-10-08 22:19:36
쿼리작성은 제가 미진하여 조언드리기가 어렵습니다. 질문주셔서 오히려 제가 공부가 되었네요



728x90

+ Recent posts