4

I have read some documentation about indexes, I did some examples and now I have some doubts.

I create a table and insert random values, (A column has unique values) column A NOT NULL I create an index on 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
...

Documentation says when all query values are in the index, the values are gathered from index (INDEX FAST FULL SCAN), but here optimizer is choosing another operation.

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      |       |       |       |
--------------------------------------------------------------------

I have to specify a hint to optimizer choose INDEX FAST FULL SCAN (but i dont know why i have to specify it)

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 |
--------------------------------------------------------------------

By the other hand ,this examples shows what oracle documentation says. When there is a value in the query that is not in the index, this value is accessed by TABLE ACCESS BY INDEX 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                |       |       |
--------------------------------------------------------------------------------

My question is ,in the first example why Oracle CHOOSE INDEX RANGE SCAN over FAST FULL INDEX SCAN.

4

1 回答 1

7

由于 SQL 语句的 WHERE 子句,您正在执行 INDEX RANGE SCAN:

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

我在这里假设您在 A 上没有唯一索引,尽管列的唯一性,即您的表 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);

由于您没有唯一索引,Oracle 无法确定 A 中的值将始终是唯一的;但是,Oracle 确实知道 A 是索引中的第一列,并且可以在索引中可用的值范围内找到该值。

如果您的 WHERE 子句尝试基于列 C 进行过滤,您将执行 INDEX FULL SCAN,因为 C 存在于索引中,因此您不需要访问表,但它不是索引中的第一列:

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 |
-------------------------------------------------------------------------------------------
于 2014-10-11T13:12:09.450 回答