programing

WHERE 절과 함께 사용할 경우 Oracle CONNECT BY 최적화

batch 2023. 6. 20. 21:27
반응형

WHERE 절과 함께 사용할 경우 Oracle CONNECT BY 최적화

오라클START WITH ... CONNECT BY적용하기 전에 적용되는 절WHERE조건을 입력합니다.따라서 WHERE 제약은 최적화에 도움이 되지 않습니다.CONNECT BY.

예를 들어, 다음 쿼리는 전체 테이블 검색을 수행할 가능성이 높습니다(선택 사항 무시).dept_id):

SELECT * FROM employees 
WHERE dept_id = 'SALE'
START WITH manager_id is null
CONNECT BY PRIOR employee_id = manager_id

저는 두 가지 방법으로 성능을 개선하려고 노력했습니다.

쿼리 A:

SELECT * FROM employees 
START WITH manager_id is null AND dept_id = 'SALE'
CONNECT BY PRIOR employee_id = manager_id

쿼리 B:

SELECT * FROM (
               SELECT * FROM employees 
                WHERE dept_id = 'SALE'
              )
START WITH manager_id is null
CONNECT BY PRIOR employee_id = manager_id

두 쿼리 모두 원래 쿼리보다 훨씬 더 잘 수행되었지만 Oracle 10g Release 2에서는 쿼리 B가 A보다 훨씬 더 잘 수행되었습니다.

다음과 관련하여 비슷한 성능 최적화를 수행했습니까?CONNECT BY그리고.WHERE조항?A 쿼리보다 B 쿼리가 훨씬 더 잘 수행되고 있다는 것을 어떻게 설명하시겠습니까?

질의 A는 영업부의 관리자들부터 시작해서 모든 직원들을 데려오라고 말합니다.Oracle은 반환된 모든 직원이 영업부에 쿼리가 포함된다는 을 "알고" 있지 않으므로, CONNECT BY를 수행하기 전에 해당 정보를 사용하여 작업할 데이터 집합을 줄일 수 없습니다.

쿼리 B는 작업할 데이터 집합을 영업부의 해당 직원에게만 명시적으로 축소합니다. 그러면 Oracle이 CONNECT BY를 수행하기 전에 수행할 수 있습니다.

이를 통해 최고의 성능을 얻을 수 있습니다.

CREATE INDEX i_employees_employee_manager_dept ON employees (employee_id,manager_id,dept_id);
CREATE INDEX i_employees_manager_employee_dept ON employees (manager_id,employee_id,dept_id);

SELECT * FROM employees  
START WITH manager_id is null AND dept_id = 'SALE' 
CONNECT BY PRIOR employee_id = manager_id AND dept_id = 'SALE' 

인덱스와 둘 다 필요합니다.AND최적화가 작동하기 위한 조건.

이것은 유사한 쿼리입니다. 짧은 이야기지만 이전 옵션에 의한 이중 연결보다 중첩된 SQL을 사용하여 더 빨리 작동했습니다.

'SELECT level, XMLElement("elemento", XMLAttributes(codigo_funcion as "Codigo",
                                                    nombre_funcion as "Nombre",
                                                    objetivos as "Objetivos",
                                                     descripcion as "Descripción",
                                                    ''rightHanging'' as "layout"))
   FROM (
           SELECT * FROM dithe_codigo_funcion 
           WHERE nodo_raiz = ''PEP''
    )      
   START WITH codigo_funcion = ''PEP'' 
   CONNECT BY PRIOR codigo_funcion = nivel_anterior'; 

따라서 전문 지식이 많지 않은 제가 추천하는 것은 중첩된 SQL을 사용하여 필터링하는 것입니다.

직원들에 대한 지표는 무엇입니까?당신은 직원 ID에 대한 색인을 가지고 있어야 합니다.그리고 직원 ID를 기본 키로 선언한 결과로 이러한 키가 있을 수 있습니다.

managerid의 인덱스를 사용하면 성능이 향상될 수도 있습니다.먹어봐.이는 신규 직원을 배치하거나 관리 관계를 재구성할 때의 성과 저하와 균형을 맞춰야 합니다.

언급URL : https://stackoverflow.com/questions/1081570/optimizing-oracle-connect-by-when-used-with-where-clause

반응형