簡體   English   中英

為什么Oracle選擇FAST FULL FIND INDEX SCAN進行索引范圍掃描

[英]Why oracle CHOOSE INDEX RANGE SCAN over FAST FULL INDEX SCAN

我已經閱讀了一些有關索引的文檔,做了一些示例,現在我有些懷疑。

我創建一個表並插入隨機值,(A列具有唯一值)列A NOT NULL我在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
...

文檔說,當所有查詢值都在索引中時,將從索引(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 |
--------------------------------------------------------------------

另一方面,該示例顯示了oracle文檔所說的內容。 當查詢中有一個不在索引中的值時,該值將由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                |       |       |
--------------------------------------------------------------------------------

我的問題是,在第一個示例中,為什么Oracle選擇FAST FULL INDEX SCAN來進行索引范圍掃描。

由於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);

由於您沒有UNIQUE索引,因此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 |
-------------------------------------------------------------------------------------------

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM