2014-10-10 2 views
2

인덱스에 대한 몇 가지 문서를 읽었습니다. 몇 가지 예를 들었으므로 이제 몇 가지 의문점이 있습니다.오라클은 왜 전체 인덱스 스캔을 선택합니까?

내가 랜덤 값 테이블을 생성 및 삽입 A 열은 NULL 는 I는 A, B, C. (B-TREE)에 인덱스

SELECT COUNT(*) FROM DEMO_FULL_INDEX_SCAN; 
=1000 
SELECT * FROM DEMO_FULL_INDEX_SCAN; 

     A   B   C   D   E   F 
---------- ---------- ---------- ---------- ---------- ---------- 
     1   7  109   1   1   1 
     2   12   83   2   2   2 
     3   21  120   3   3   3 
     4   13   74   4   4   4 
     5   2   1   5   5   5 
... 
을 만들 NOT (A 열은 고유 한 값을 갖는다)

설명서에 따르면 모든 쿼리 값이 인덱스에있을 때 값은 인덱스 (INDEX FAST FULL SCAN)에서 수집되지만 여기서 옵티마이 저가 다른 작업을 선택합니다.

EXPLAIN PLAN FOR 
SELECT A,B,C FROM DEMO_FULL_INDEX_SCAN WHERE A = 1; 
-------------------------------------------------------------------- 
| Id | Operation   | Name  | Rows | Bytes | Cost | 
-------------------------------------------------------------------- 
| 0 | SELECT STATEMENT  |    |  |  |  | 
|* 1 | INDEX RANGE SCAN | FIS_01  |  |  |  | 
-------------------------------------------------------------------- 

내가 (하지만 난 그나마 내가 그것을 지정해야 이유를 알고) 다른 한편으로

EXPLAIN PLAN FOR 
SELECT /*+ INDEX_FFS(DEMO_FULL_INDEX_SCAN FIS_01) */A,B,C FROM DEMO_FULL_INDEX_SCAN WHERE A = 1; 
-------------------------------------------------------------------- 
| Id | Operation   | Name  | Rows | Bytes | Cost | 
-------------------------------------------------------------------- 
| 0 | SELECT STATEMENT  |    |  1 | 11 |  2 | 
|* 1 | INDEX FAST FULL SCAN| FIS_01  |  1 | 11 |  2 | 
-------------------------------------------------------------------- 

이 예 INDEX에게 FAST FULL SCAN을 선택 옵티 마이저 힌트를 지정해야 무엇 신탁 설명서를 보여줍니다 말한다. 인덱스에없는 쿼리에 값이있는 경우 ,이 값은 인덱스 테이블 액세스하여 액세스 ROWID

EXPLAIN PLAN FOR 
SELECT D FROM DEMO_FULL_INDEX_SCAN WHERE A = 800; 

-------------------------------------------------------------------------------- 
-------------------------------------------------------------------------------- 
| Id | Operation     | Name     | Rows | Bytes | Co 
-------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT   |      |  |  | 
| 1 | TABLE ACCESS BY INDEX ROWID| DEMO_FULL_INDEX_SCAN |  |  | 
|* 2 | INDEX RANGE SCAN   | FIS_01    |  |  | 
-------------------------------------------------------------------------------- 

내 질문입니다, 오라클은 FAST FULL 이상의 인덱스 범위 스캔을 선택하는 이유 첫 번째 예에서 INDEX SCAN.

select a,b,c from demo_full_index_scan where a = 1; 

난 당신이의 특수성에도 불구하고 A의 고유 인덱스를하지 않아도 여기에 있으리라 믿고있어 :

답변

5

당신 때문에 당신의 SQL 구문의 WHERE 절의 인덱스의 범위 스캔을 수행하고 열, 테이블, 즉 DDL은 다음과 같이이다 :

create table demo_full_index_scan ( 
    a number 
, b number 
, c number 
, d number 
    ); 

create index i_demo_full_index_scan on demo_full_index_scan (a, b, c); 

오라클은 A의 값은 항상 고유 것이라는 점을 확실하게 알 수없는 UNIQUE 인덱스를 가지고 있지 않기 때문에, 그러나 오라클은 A가 인덱스의 첫 번째 컬럼임을 알고 인덱스에서 사용 가능한 값 범위에서이 값을 찾을 수 있습니다.

WHERE 절이 C 열을 기준으로 필터링을 시도하면 색인에 C가 존재하므로 INDEX FULL SCAN을 수행하므로 테이블에 액세스 할 필요는 없지만 첫 번째 열은 아닙니다 색인에 :

explain plan for select a,b,c from demo_full_index_scan where c = 1; 
------------------------------------------------------------------------------------------- 
| Id | Operation  | Name     | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |      |  1 | 39 |  1 (0)| 00:00:01 | 
|* 1 | INDEX FULL SCAN | I_DEMO_FULL_INDEX_SCAN |  1 | 39 |  1 (0)| 00:00:01 | 
-------------------------------------------------------------------------------------------