IN 조건 결과와 EXISTS 결과의 차이가 납니다. 0 7 1,866

by sun [SQL Query] [2017.03.16 00:17:20]


[IN 조건 사용시 조회바로 나옴]

SELECT BRANCH_CD,CUST_NO
FROM  CR_ICP_DET_GRP_CUST A
WHERE A.BRANCH_CD   = :1
AND   A.CAMPAIGN_NO = :2
AND   A.SEQ         = :3
AND   A.GROUP_SEQ   = :4
AND   A.CUST_NO IN (SELECT CR_CONVERT_CUST_NO(C_CUST_NO)
                             FROM   CR_ICO_RESERVE AA
                             WHERE  AA.BRANCH_CD = '1000'
                            AND    NVL(AA.DEL_YN,'N') = 'N'                                                                         
                            AND   (  ( AA.RES_FR_DATE BETWEEN '20170301' AND '20170430' )
                                  OR ( AA.RES_TO_DATE BETWEEN '20170301' AND '20170430' )
                                  OR ( AA.RES_FR_DATE <= '20170301' AND '20170430' <= AA.RES_TO_DATE)
                               )
                            AND   AA.STAY_YN = 'Y'
                            AND   NVL(AA.C_CUST_NO,' ') <> ' '
                            AND   EXISTS ( SELECT 1
                                               FROM CM_TBO_CUSTGAME_DET X,
                                                        CM_TBO_TBL_MST Y
                                                       WHERE X.BRANCH_CD = Y.BRANCH_CD
                                                       AND   X.TBL_CD    = Y.TBL_CD
                                                      AND   Y.SALESL    = 'E'
                                                      AND   X.BRANCH_CD = AA.BRANCH_CD
                                                      AND   X.C_CUST_NO = AA.C_CUST_NO
                                                     AND   X.SALES_DATE BETWEEN AA.RES_FR_DATE AND AA.RES_TO_DATE
                                                      AND   X.DEL_YN  = 'N')
                           GROUP BY AA.BRANCH_CD,AA.C_CUST_NO
                           HAVING  COUNT(*) > 0 )

 

[위의 구문을 EXISTS로 바꿔봄 => 계속 조회중으로 나옴=> 너무 길어 계속 기다려보진 않음]

 

SELECT BRANCH_CD,CUST_NO
FROM  CR_ICP_DET_GRP_CUST A
WHERE A.BRANCH_CD   = :1
AND   A.CAMPAIGN_NO = :2
AND   A.SEQ         = :3
AND   A.GROUP_SEQ   = :4
AND   EXISTS    (
            SELECT 1
            FROM   CR_ICO_RESERVE AA
            WHERE  AA.BRANCH_CD = A.BRANCH_CD
            AND    AA.C_CUST_NO  = CR_CONVERT_CUST_NO(A.CUST_NO)
            AND    AA.DEL_YN = 'N'                                                                         
            AND   (  ( AA.RES_FR_DATE BETWEEN '20170301' AND '20170430' )
                  OR ( AA.RES_TO_DATE BETWEEN '20170301' AND '20170430' )
                  OR ( AA.RES_FR_DATE <= '20170301' AND '20170430' <= AA.RES_TO_DATE)
                  )
            AND   AA.STAY_YN = 'Y'
            AND   NVL(AA.C_CUST_NO,' ') <> ' '
            AND   ROWNUM = 1
            AND   EXISTS ( SELECT 1
                           FROM CM_TBO_CUSTGAME_DET X,
                                CM_TBO_TBL_MST Y
                           WHERE X.BRANCH_CD = Y.BRANCH_CD
                           AND   X.TBL_CD    = Y.TBL_CD
                           AND   Y.SALESL    = 'E'
                           AND   X.BRANCH_CD = AA.BRANCH_CD
                           AND   X.C_CUST_NO = AA.C_CUST_NO
                           AND   X.SALES_DATE BETWEEN AA.RES_FR_DATE AND AA.RES_TO_DATE
                           AND   X.DEL_YN  = 'N')
             GROUP BY AA.BRANCH_CD,AA.C_CUST_NO
             HAVING  COUNT(*) > 0 ) ;

위의 둘 차이가 뭐길래 EXISTS일때는 계속 조회중일까요?

 

 

by jkson [2017.03.16 08:41:00]

정확한 건 실행계획을 보아야 알겠지만 일단 차이 나는 것은 in절에는 branch_cd가 1000으로 고정이네요.


by sun [2017.03.16 09:33:44]

아.. '1000' 은 제가 테스트하느라 그렇게 썼습니다만..    :1로 파라미터 수정해서 조회하면  조회 잘되고 있어요.

죄송하지만 다시한번 부탁드리겠습니다.

 


by jkson [2017.03.16 09:51:40]

쿼리만 봐서는 어느 누구도 무엇이 문제인지 정확히 알기는 어려울 것 같은데요.

실행계획을 보여주셔야 무엇이 문제인지 파악할 수 있지 않을까요?

exists절에도

AA.BRANCH_CD = A.BRANCH_CD

-> AA.BRANCH_CD = :1 로 바꾸어보세요.


by 마농 [2017.03.16 09:52:54]

1. 함수 사용 위치가 바뀐 듯 하네요.
  - 기존쿼리에는 c_cust_no 에 함수 사용했는데
  - 변경쿼리에는 a.cust_no 에 함수 사용하네요?
  - 함수의 사용 위치 맞는지 확인하시구요.
  - 함수의 역할이 뭔지? 꼭 사용해야 하는지?
  - 사용자 함수를 내장 함수로 변경할수는 없는지?
  - 등을 검토해 보세요.
2. 구간 검색 조건을 OR 로 복잡하게 작성하셨는데요?
  - 간단하게 시작과 종료를 교차비교하면 됩니다.
  - AND aa.res_fr_date <= '20170430'
  - AND aa.res_to_date >= '20170301'
3. 수행 시간의 차이는
  - 실행계획을 비교해 보세요.


by 마농 [2017.03.16 10:19:02]

GROUP BY 와 HAVING 절 빼시는게 좋을 듯 하네요.


by 느훼훼 [2017.03.16 10:37:56]

쿼리 자체를 전면 수정해야할듯요.. exists안에 또 exists;; 또 exists구문안에 있는 쿼리 자체가 너무 길고..

꼭 저리 짜야만 했나요? 좀 더 깔끔하게 짜셔야 할듯요.


by sun [2017.03.16 13:47:45]

여러분들 답변 주셔서 .. 감사합니다.

쿼리를 짜다보니 어쩌다가 저렇게 되었네요..

많은 참고 되었습니다.

매번 도움 주시는 분들 정말 감사드립니다.

 

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