2013-05-18 2 views
-1
PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------------- 
Plan hash value: 2822030489 
--------------------------------------------------------------------------------------------- 

| Id | Operation     | Name   | Rows | Bytes | Cost (%CPU)| Time  | 
--------------------------------------------------------------------------------------------- 
PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT   |    |  1 | 46 |  2 (0)| 00:00:01 | 
| 1 | TABLE ACCESS BY INDEX ROWID| PURCHASE  |  1 | 46 |  2 (0)| 00:00:01 | 
|* 2 | INDEX UNIQUE SCAN   | PK_PURCHASENO |  1 |  |  1 (0)| 00:00:01 | 
--------------------------------------------------------------------------------------------- 
PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 
2 - access("PURCHASENO"=9989) 

14 rows selected. 

누군가가 내게 어떤 의미인지 설명 할 수 있습니까?쿼리 실행을위한 Oracle 옵티 마이저

Oracle이이 쿼리를 실행하기 위해 인덱싱을 사용한다는 의미입니까?

+0

'PURCHASENO'는 기본 키이며 고유 인덱스가 정의되어 있으므로 예 - oracle이 인덱스 액세스 경로를 선택합니다. – haki

+0

'INDEX UNIQUE SCAN' 단서가 아닌가요? [성능 조정 가이드] (http://docs.oracle.com/cd/E29597_01/server.1111/e16638/optimops.htm#i82029)를 보았습니까? –

+0

@AlexPoole 네,이 질문에 완전히 대답하기 위해 최선을 다하고 싶습니다. – Jim

답변

1

단서는 계획에 있습니다.

즉, 인덱스 PK_PURCHASENO를 고유하게 검색하고 있음을 의미합니다.

| Operation   | Name   | Rows | 
--------------------------------------------- 
| INDEX UNIQUE SCAN | PK_PURCHASENO |  1 | 

나는이 기본 키라는 이름으로 가정하고 쿼리가 PURCHASENO 열을의에 의해 판단하고 있습니다. 기본 키는 고유해야하므로 놀랄 정도는 아닙니다. 열은 this.a를 확인하는 하나의 행만 반환한다는 것을 나타냅니다.

다른 중요한 것은이 행입니다.

| Id | Operation     | Name   | Rows | Bytes | 
--------------------------------------------------------------------- 
| 1 | TABLE ACCESS BY INDEX ROWID| PURCHASE  |  1 | 46 | 

당신은 고유 인덱스를 스캔했지만 그냥 인덱스에서 데이터를 선택하지 않는, 당신은 또한 당신이 select *을 작성한으로 테이블에서 데이터를 반환해야합니다. ROWID는 행을 식별하는 테이블의 고유 한 주소입니다. ROWID로 (단일) 행에 액세스하는 것은 데이터를 반환하는 가장 빠른 방법입니다. 오라클은 기본 키 인덱스에서 원하는 행을 찾은 다음 rowid를 사용하여 나머지 행을 선택합니다. 바이트 열에 46이 있다는 것을 알게되면 행의 길이가 46 바이트임을 의미합니다.

당신이 대신 ROWID에 의한 액세스가 더 이상 필요하지 않을 것입니다 다음 쿼리를 사용했다 :

select purchaseno 
    from purchase 
where purchaseno = 1000 

열 PURCHASENO 인덱스에 이미 있기 때문입니다; 테이블에 액세스 할 필요가 없습니다. select *은 "해로운"것으로 간주되므로 디스크에서 읽어야하는 데이터의 양과 잠재적으로 네트워크를 통해 보내야하는 데이터의 양이 증가 할뿐만 아니라 추가로 데이터를 읽어야 할 수도 있습니다 데이터에 액세스하기위한 작업 필요한 행만 선택하십시오.

마지막 두 점인 PUCRHASENO 값은 숫자 임에도 불구하고 따옴표로 묶여 있습니다. PURCHASENO가 실제로 문자 일 경우 이것은 괜찮습니다. 그러나 숫자 일 경우 암시 적으로 문자를 숫자로 변환 할 때 여기에 어떤 위험이 있습니다. 다음과 같은 이유로 오라클 explicitly recommends against implicit conversion :

  • SQL 문은 명시 적 데이터 형식 변환 기능을 사용하면 쉽게 이해할 수 있습니다.

  • 특히, 열 값의 데이터 유형이 다른 값보다는 상수 값으로 변환되는 경우, 내재적 데이터 유형 변환은 성능에 부정적인 영향을 줄 수 있습니다.

  • 암시 적 변환은 발생하는 상황에 따라 다르며 모든 경우에 동일한 방식으로 작동하지 않을 수 있습니다. 예를 들어, datetime 값에서 VARCHAR2 값으로의 암시 적 변환은 NLS_DATE_FORMAT 매개 변수의 값에 따라 예상치 못한 연도를 반환 할 수 있습니다.

  • 암시 적 변환을위한 알고리즘은 소프트웨어 릴리스 및 Oracle 제품간에 변경 될 수 있습니다. 명시 적 전환의 행동이 더 예측 가능합니다.

이 당신처럼 간단한 쿼리에서 일어날 가능성이 있지만이 , 당신은 인덱스를 사용하지 않는 것이 충분히 최적화를 혼동 할 수있다 이렇게.

마지막으로 이것은 개인적인 취향입니다. PURCHASE 테이블의 기본 키 이름이 다소 혼란 스럽습니다. 더 나은 표준은 이 아니고 PK_<column name>이 될 수 있습니다. 테이블에는 기본 키가 하나만있을 수 있으며 해당 이름의 개체 하나만 하나의 스키마에있을 수 있습니다. 그러나 기본 키와 동일한 열 이름을 가진 두 개의 테이블을 가질 수 있습니다.

오라클 성능 튜닝 가이드에는 reading and understanding explain plans에 대한 장이 있으며,이 장의 내용을 읽는 것이 좋습니다.

+0

고맙습니다. – Jim

관련 문제