데이터가 몇건 안되는데, outer join시 속도문제 문의 0 7 1,696

by 패대기 [SQL Query] [2022.10.27 18:06:56]


안녕하세요. 

쿼리속도문제 문의 드립니다.

2개의 with문으로 된 데이터이며, A테이블은 3건, B테이블(DBLINK사용)은 0건 조회됩니다.

각각 WITH문은 속도가 빠르며, 

JOIN시 속도는 빠른데, OUTER JOIN시 속도가 엄청 느립니다.

 

쿼리예제)

WITH A_DATA AS (
      SELECT *  --DATA 3건 조회됨: 쿼리 속도빠름
       FROM 업무테이블
      WHERE ...
 )
 , B_DATA AS (
   SELECT *  --0건조회됨 : : 쿼리 속도빠름
   FROM DBLINK테이블
   WHERE ...
 )
SELECT *
FROM A_DATA A
   , B_DATA B
WHERE A.KEY = B.KEY(+) -- > 속도 느림. JOIN시 속도 빠름

 

뭐가 문제일까요? WITH문은 각각 데이터 조회 후 마지막에 처리하는거 아닌지요?

해결 방법이 있는지 문의 드립니다.

 

감사합니다.

 

by 우리집아찌 [2022.10.28 10:50:02]

with 절을 inline 으로 바꿔보세요   

그리고 db링크 사용시 인덱스를 타는지 확인해보세요.


by 패대기 [2022.10.28 13:05:19]

INLINE으로 해도 같은 현상입니다. OUTER JOIN처리만 하면 엄청 늦네요..ㅠ


by 우리집아찌 [2022.10.28 13:09:52]

xplan 떠서 확인해보세요


by 마농 [2022.10.31 16:10:25]

대용량도 아니고 극소량 3건, 0건인데? 오래 걸린다면?
- 조회량은 작지만, 전체 데이터량은 많을 것 같고
- 조인키에 대한 적절한 인덱스가 없을 것 같습니다.
실행계획을 확인해야 하겠지만
- 이너조인은 조인 방향이 B > A 일 것 같고
- 아우터조인은 조인 방향이 A > B 일 것 같네요
- B 에 적절한 인덱스가 없어서 풀스캔을 하는게 아닐까? 생각됩니다.
만약 조회량이 항상 소량이라면?
- /*+ materialize */ 힌트를 사용해 보세요.
- WITH 구문을 풀어해치지 않고 먼저 수행합니다.

WITH a_data AS
(
SELECT /*+ materialize */
       *
  FROM 업무테이블
 WHERE ...
)
, b_data AS
(
SELECT /*+ materialize */
       *
  FROM DBLINK테이블
 WHERE ...
)
SELECT *
  FROM a_data a
     , b_data b
 WHERE A.KEY = B.KEY(+)
;

 


by 패대기 [2022.11.01 09:23:43]

마농님, 천재이십니다. 해당 힌트 사용하니 아주 잘됩니다. 정말 정말 고맙습니다.

하나 궁금한것이 WITH문 각각 결과에 대해서 JOIN되는것이 아닌가요? 

WITH문 결과가 적은것과 쿼리속도랑 별개이며, 실행시 내부적으로 WITH문도 풀어서 실행되나 보네요..


by 마농 [2022.11.01 09:43:55]

작성한 쿼리대로 동작하지 않고 쿼리변환이라는 과정을 통해 쿼리를 최적화 시켜서 실행하게 됩니다.
인라인뷰를 풀어서 메인쿼리와 합치는 뷰머징도 쿼리변환의 하나이구요.
뷰머징이 가능한 경우가 있고 그렇지 않은 경우가 있는데
가능한 경우라면 뷰머징이 동작할 가능성이 높습니다.

WITH 문은 인라인뷰와 동일하게 동작합니다.
만약 WITH 문의집합이 여러번 재사용된다면 인라인뷰와 다르게 동작할 수 있습니다.
materialize 힌트는 WITH 문이 풀어지지 않도록 하는 힌트입니다.

뷰머징이 동작하지 않도록 ROWNUM 을 추가하는 방법도 시도해 보세요.
 

WITH a_data AS
(
SELECT *
  FROM 업무테이블
 WHERE ...
)
, b_data AS
(
SELECT b.*
     , ROWNUM rn
  FROM DBLINK테이블 b
 WHERE ...
)
SELECT *
  FROM a_data a
     , b_data b
 WHERE A.KEY = B.KEY(+)
;

 


by 패대기 [2022.11.01 10:07:14]

감사합니다. 많이 배웁니다.

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