문제

나는 내 Where 절에 일련의 조건이 있습니다.

WHERE 
d.attribute3 = 'abcd*'  
AND x.STATUS != 'P' 
AND x.STATUS != 'J' 
AND x.STATUS != 'X' 
AND x.STATUS != 'S' 
AND x.STATUS != 'D' 
AND CURRENT_TIMESTAMP - 1 < x.CREATION_TIMESTAMP

이러한 조건 중 어느 조건이 먼저 실행됩니까? 나는 Oracle을 사용하고 있습니다.

실행 계획에서 이러한 세부 정보를 얻을 수 있습니까? (나는 여기 DB에서 그렇게 할 권한이 없다. 그렇지 않으면 시도했을 것이다)

도움이 되었습니까?

해결책

당신은 확실한 실행 계획을 볼 수있는 "권한이 없다"고? Autotrace를 사용하는 것은 어떻습니까?

SQL> set autotrace on
SQL> select * from emp
  2  join dept on dept.deptno = emp.deptno
  3  where emp.ename like 'K%'
  4  and dept.loc like 'l%'
  5  /

no rows selected


Execution Plan
----------------------------------------------------------

----------------------------------------------------------------------------------
| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)|
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |              |     1 |    62 |     4   (0)|
|   1 |  NESTED LOOPS                |              |     1 |    62 |     4   (0)|
|*  2 |   TABLE ACCESS FULL          | EMP          |     1 |    42 |     3   (0)|
|*  3 |   TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)|
|*  4 |    INDEX UNIQUE SCAN         | SYS_C0042912 |     1 |       |     0   (0)|
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("EMP"."ENAME" LIKE 'K%' AND "EMP"."DEPTNO" IS NOT NULL)
   3 - filter("DEPT"."LOC" LIKE 'l%')
   4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")

보시다시피, 그것은 쿼리가 어떻게 실행되는지에 대한 많은 세부 사항을 제공합니다. 그것은 다음을 말해줍니다.

  • EMP의 전체 스캔에서 "emp.ename like 'k%'"조건이 먼저 적용됩니다.
  • 그러면 매칭 부서는 Dept.deptno의 색인을 통해 선택됩니다 (중첩 루프 방법을 통해)
  • 마지막으로 필터 "Dept.loc Like 'L%'가 적용됩니다.

이 응용 프로그램 순서는이 재주문 쿼리와 함께 표시 할 수 있듯이 where 조항에서 Predicates가 주문되는 방식과 관련이 없습니다.

SQL> select * from emp
  2  join dept on dept.deptno = emp.deptno
  3  where dept.loc like 'l%'
  4  and emp.ename like 'K%';

no rows selected


Execution Plan
----------------------------------------------------------

----------------------------------------------------------------------------------
| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)|
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |              |     1 |    62 |     4   (0)|
|   1 |  NESTED LOOPS                |              |     1 |    62 |     4   (0)|
|*  2 |   TABLE ACCESS FULL          | EMP          |     1 |    42 |     3   (0)|
|*  3 |   TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)|
|*  4 |    INDEX UNIQUE SCAN         | SYS_C0042912 |     1 |       |     0   (0)|
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("EMP"."ENAME" LIKE 'K%' AND "EMP"."DEPTNO" IS NOT NULL)
   3 - filter("DEPT"."LOC" LIKE 'l%')
   4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")

다른 팁

데이터베이스는 조건을 실행할 주문을 결정합니다.

일반적으로 (항상 그렇지는 않지만) 가능한 경우 먼저 색인을 사용합니다.

말했듯이 실행 계획을 살펴보면 정보가 제공됩니다. 그러나 계획 안정성 기능을 사용하지 않으면 항상 실행 계획에 의존 할 수는 없습니다.

게시 한 쿼리의 경우 평가 순서가 어떤 방식 으로든 논리를 변경하는 것처럼 보이지 않으므로, 당신이 생각하는 것은 효율성이라고 생각합니다. Oracle Optimizer가 효율적인 계획을 선택할 가능성이 상당히 높습니다.

성능을 기본 쿼리와 비교하려면 특정 순서를 장려하기 위해 할 수있는 트릭이 있습니다. 예를 들어 타임 스탬프 조건이 먼저 실행되기를 원한다고 말하십시오. 당신은 이것을 할 수 있습니다 :

WITH subset AS
  ( SELECT /*+ materialize */
      FROM my_table
      WHERE CURRENT_TIMESTAMP - 1 < x.CREATION_TIMESTAMP
  )
SELECT *
  FROM subset
  WHERE 
  d.attribute3 = 'abcd*'  
  AND x.STATUS != 'P' 
  AND x.STATUS != 'J' 
  AND x.STATUS != 'X' 
  AND x.STATUS != 'S' 
  AND x.STATUS != 'D'

"구체화"힌트는 Optimizer가 먼저 쿼리를 실행 한 다음 다른 조건에 대한 결과 세트를 스캔해야합니다.

나는 당신이 이것을 일반적인 습관으로 조언하지 않습니다. 대부분의 경우 간단한 쿼리를 작성하면 최상의 실행 계획으로 이어집니다.

실행 계획에 대한 다른 의견에 추가하기 위해, 9i에 도입되고 10G+ Oracle에서 기본적으로 사용 된 CPU 기반 원가 계산 모델에 따라, 또한 어떤 술어 평가 순서가 어떤 식 사례 평가 순서를 평가할 것입니다. 테이블 액세스 순서 및 방법. 하나의 술어를 실행하기 전에 하나의 술어를 실행하면 더 적은 수의 사전 계산이 실행되는 경우 최 Optimisaton을 적용 할 수 있습니다.

자세한 내용은이 기사를 참조하십시오. http://www.oracle.com/technology/pub/articles/lewis_cbo.html

또한, Oracle은 체크 제약 조건 또는 파티션 정의와 비교하면 어쨌든 행이 반환되지 않는다는 것을 나타내는 Predicates를 실행할 필요조차 없습니다.

복잡한 것들.

마지막으로, 관계형 데이터베이스 이론은 당신이 할 수 있다고 말합니다 절대 쿼리 클로스의 실행 순서에 따라 다르므로 시도하지 않는 것이 가장 좋습니다. 다른 사람들이 말했듯이, 비용 기반 최적화기는 그것이 가장 좋은 생각을 선택하려고하지만 심지어보기까지합니다. 계획을 설명하십시오 습관 보장하다 사용 된 실제 순서. 설명 계획은 CBO가 권장하는 것을 알려주지 만 여전히 100%가 아닙니다.

왜 당신 이이 일을하려고하는지 설명한다면 일부는 계획을 제안 할 수 있습니까?

까다로운 질문. 방금 같은 딜레마에 직면했습니다. 쿼리 내에서 함수를 언급해야합니다. 함수 자체는 또 다른 쿼리를 만들므로 성능에 일반적으로 성능에 어떤 영향을 미치는지 이해합니다. 그러나 대부분의 경우 나머지 조건이 먼저 실행되면 기능을 자주 호출하지 않습니다.

글쎄, 주제에 대한 또 다른 기사를 여기에 게시하는 것이 유용 할 것이라고 생각했습니다.

다음 인용문은에서 복사되었습니다 도널드 벌레슨의 사이트 (http://www.dba-oracle.com/t_where_clause.htm) .

그만큼 ordered_predicates 힌트는 쿼리의 절을 여기서 Oracle에 지정되며 부울 곤경을 평가 해야하는 순서를 지정하는 데 사용됩니다.

에서 Ordered_predicates의 부재, Oracle은 다음 단계를 사용하여 SQL Predicates의 순서를 평가합니다.

  • 하위 쿼리는 WHERE 절의 외부 부울 조건 전에 평가됩니다.

  • 내장 함수 또는 하위 쿼리가없는 모든 부울 조건은 WHERE 절에서 찾은 순서에서 반대로 평가되며 마지막 술어는 먼저 평가됩니다.

  • 각 술집의 내장 기능을 갖춘 부울은 예상 평가 비용의 순서로 평가됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top