2009-06-25 5 views
2

리팩터링 작업을 수행하는 다소 복잡한 쿼리를 상속 받았습니다.인라인 뷰에서 술어를 사용하면 쿼리 속도가 느려질 수 있습니까?

이 과정에서 개인적 취향으로 인해 수행 한 작업 중 하나는 ANSI-99 조인 구문을 모두 "내부 조인"및 "왼쪽 외부 조인"문에서 쿼리의 조건부로 변경하는 것이 었습니다. 나는 2 가지의 매우 이상한 것들을 알아 차렸다.

  1. "INNER JOIN ..."구문에서 조인을 변경하면 Explain 플랜이 변경되었습니다. ANSI 99 구문을 사용하여 oracle은 조인중인 열에 대한 전체 테이블 스캔을 수행했습니다. 조인 구문을 변경 한 후 이제 술어 푸시를 수행합니다. 조인 구문이 Explain 계획을 변경하는 이유는 무엇입니까?
  2. 인라인보기를 밀어 넣는 조건부로 인해 실제로 쿼리의 처리 속도가 상당히 느려졌습니다. 조인을 변경하기 전에 실행중인 쿼리가 약 3 초. 이제 9 초가 걸립니다. 솔직히 말해서, 나는 계획을 설명하는 것에 상당히 익숙하지 않기 때문에 쿼리의 구조 조정이 다른 이유로 느려질 가능성이 완전히 있습니다. 그러나 궁극적으로 제 질문은 "쿼리가 너무 느려지도록 인덱싱 된 열을 조건부로 밀어 넣을 수 있습니까? 그렇다면 이유는 무엇입니까?"

답장을 주셔서 감사합니다, 내 사과이 명확하지 않은 경우 ...

+0

이전 및 이후 쿼리를 게시하십시오. 변경 사항이 "구문 변경"이상의 것일 수 있습니다 - 쿼리의 의미가 변경되거나 (또는 ​​최적화 프로그램에서 사용 가능한 정보를 추가/제거하는 경우) 영향을 미칠 수 있습니다 상당히 계획. –

답변

3

그렇게 실질적으로 쿼리를 천천히 인덱스 컬럼에 밀어 술어 수 있습니까? 그렇다면 왜?

물론입니다.

일반적으로 조건부 푸시를 사용하면 옵티마이 저가 HASH JOIN 대신 NESTED LOOPS을 선택합니다.

조건이 선택적이 아닌 경우 속도가 느려질 수 있습니다.

SELECT * 
FROM table1, t1 
     (
     SELECT /*+ NO_PUSH_PRED */ 
       * 
     FROM table2 t2 
     WHERE t2.col1 = :value1 
     ) t2o 
WHERE t2o.col2 = t1.col2 

대부분의 아마 table1의 내용을 통해 해시 테이블을 구축하고,이 해시 테이블 (또는 그 반대)에 대한 뷰에 의해 반환 된 행을 조사합니다이 쿼리.

이 쿼리는 :

SELECT * 
FROM table1, t1 
     (
     SELECT /*+ PUSH_PRED */ 
       * 
     FROM table2 t2 
     WHERE t2.col1 = :value1 
     ) t2o 
WHERE t2o.col2 = t1.col2 

NESTED LOOPS(t2.col1, t2.col2)에 인덱스가 정의되어있는 경우를 사용합니다.

col2table2에서 선택하면 후자가 더 효율적이며 그렇지 않은 경우 효율성이 떨어집니다.

필자의 경험에 비추어 볼 때 나는 당신의 경우에 일어난 일이라고 생각합니다.

쿼리 및 실행 계획을 게시하면 더 많이 말할 수 있습니다.

+0

설명해 주셔서 감사합니다. 술어 푸싱을 사용하고 있다면 단순히 조인 구문을 변경하는 것이 일반적일까요? – jnt30

+0

@ jnt30 : 오라클의 옵티마이 저는 예측할 수없는 방식으로 작동 할 수 있습니다. 최악의 경우 10 초 이상 실행되는 모든 쿼리를 개인적으로 설명합니다. – Quassnoi

+0

@Quassnoi : 알겠습니다. 고마워요. 나는 이것에 관해 당신의 게시물 중 몇 가지를 보았습니다. 나는 그것들을 살펴보고 모든 것을 이해하려고 노력할 것입니다. 나는 주로 Java 개발자 였으므로이 중 일부는 나에게 매우 새로운 것이다. 제 질문에 대답 해 주셔서 감사합니다. – jnt30

관련 문제