full index scan and fast full index scan

官方文檔:
Full Index Scan
In a full index scan, the database reads the entire index in order. A full index scan is available if a predicate (WHERE clause) in the SQL statement references a column in the index, and in some circumstances when no predicate is specified. A full scan can eliminate sorting because the data is ordered by index key.
Fast Full Index Scan
A fast full index scan is a full index scan in which the database reads the index blocks in no particular order. The database accesses the data in the index itself, without accessing the table.

Fast full index scans are an alternative to a full table scan when the index contains all the columns that are needed for the query, and at least one column in the index key has the NOT NULL constraint.

理解:
full index scan:想要的結果是有序,讀取數據塊是一塊一塊的操作,他會從索引的根節點向下掃描到葉子節點,然後使用雙向列表的方式順序讀取數據塊。
fast full index scan:想要的結果是無序的,讀取數據塊是multiple I/O操作,從根幾點開始向下掃描到葉子節點後使用的是單次I/O讀取多個數據塊。
例子:
index fast full scan與index full scan試驗
--創建測試表test3
SQL> create table test3 as select * from dba_objects;

表已創建。
--創建索引
SQL> create index idx_test3_id on test3(object_id);

索引已創建。

--收集test3的統計信息
SQL> exec dbms_stats.gather_table_stats('SYSTEM','TEST3',cascade=>true);

PL/SQL 過程已成功完成。

SQL> set autot traceonly;
SQL> select object_id from test3;

已選擇71947行。


執行計劃
----------------------------------------------------------               
Plan hash value: 3306317399                                              
                                                                         
---------------------------------------------------------------------------                                                                                                         
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                         
---------------------------------------------------------------------------                                                                                                         
|   0 | SELECT STATEMENT  |       | 71947 |   351K|   280   (1)| 00:00:04 |                                                                                                         
|   1 |  TABLE ACCESS FULL| TEST3 | 71947 |   351K|   280   (1)| 00:00:04 |                                                                                                         
---------------------------------------------------------------------------                                                                                                         


統計信息
----------------------------------------------------------               
          1  recursive calls                                             
          0  db block gets                                               
       5760  consistent gets                                             
          0  physical reads                                              
          0  redo size                                                   
     843616  bytes sent via SQL*Net to client                            
      53148  bytes received via SQL*Net from client                      
       4798  SQL*Net roundtrips to/from client                           
          0  sorts (memory)                                              
          0  sorts (disk)                                                
      71947  rows processed    
--我們看見上面的執行計劃走了全表掃描,這是因爲沒有對oracle索引中不會存儲null值,
而我們的查詢中有要返回所有的值,索引會走全表掃面。                                        
--如果此時加上限定條件 where objec_id is not null 則會走 index fast full scan
-更改列object_id屬性爲 not null
SQL> alter table test3 modify (object_id not null);

表已更改。

SQL> select object_id from test3;

已選擇71947行。


執行計劃
----------------------------------------------------------               
Plan hash value: 1226029696                                              
                                                                         
-------------------------------------------------------------------------------------                                                                                               
| Id  | Operation            | Name         | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                               
-------------------------------------------------------------------------------------                                                                                               
|   0 | SELECT STATEMENT     |              | 71947 |   351K|    45   (0)| 00:00:01 |                                                                                               
|   1 |  INDEX FAST FULL SCAN| IDX_TEST3_ID | 71947 |   351K|    45   (0)| 00:00:01 |                                                                                               
-------------------------------------------------------------------------------------                                                                                               


統計信息
----------------------------------------------------------               
        208  recursive calls                                             
          0  db block gets                                               
       4982  consistent gets                                             
          0  physical reads                                              
          0  redo size                                                   
     843616  bytes sent via SQL*Net to client                            
      53148  bytes received via SQL*Net from client                      
       4798  SQL*Net roundtrips to/from client                           
          6  sorts (memory)                                              
          0  sorts (disk)                                                
      71947  rows processed                                              
--如上所示,限定爲not null 後走了index fast full scan
--添加限定條加走 index full scan                                       
SQL> select /*+ index(test3 idx_test3_id) */ object_id from test3;

已選擇71947行。


執行計劃
----------------------------------------------------------               
Plan hash value: 3789893995                                              
                                                                         
---------------------------------------------------------------------------------                                                                                                   
| Id  | Operation        | Name         | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                   
---------------------------------------------------------------------------------                                                                                                   
|   0 | SELECT STATEMENT |              | 71947 |   351K|   160   (0)| 00:00:02 |                                                                                                   
|   1 |  INDEX FULL SCAN | IDX_TEST3_ID | 71947 |   351K|   160   (0)| 00:00:02 |                                                                                                   
---------------------------------------------------------------------------------                                                                                                   


統計信息
----------------------------------------------------------               
          1  recursive calls                                             
          0  db block gets                                               
       4946  consistent gets                                             
          0  physical reads                                              
          0  redo size                                                   
     843616  bytes sent via SQL*Net to client                            
      53148  bytes received via SQL*Net from client                      
       4798  SQL*Net roundtrips to/from client                           
          0  sorts (memory)                                              
          0  sorts (disk)                                                
      71947  rows processed                                              
--添加order by也會走index full scan,這裏會注意到index full scan的開銷是160,
而index fast full scan的開銷只有45
SQL> select object_id from test3 order by object_id;

已選擇71947行。


執行計劃
----------------------------------------------------------               
Plan hash value: 3789893995                                              
                                                                         
---------------------------------------------------------------------------------                                                                                                   
| Id  | Operation        | Name         | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                   
---------------------------------------------------------------------------------                                                                                                   
|   0 | SELECT STATEMENT |              | 71947 |   351K|   160   (0)| 00:00:02 |                                                                                                   
|   1 |  INDEX FULL SCAN | IDX_TEST3_ID | 71947 |   351K|   160   (0)| 00:00:02 |                                                                                                   
---------------------------------------------------------------------------------                                                                                                   


統計信息
----------------------------------------------------------               
          1  recursive calls                                             
          0  db block gets                                               
       4946  consistent gets                                             
          0  physical reads                                              
          0  redo size                                                   
     843616  bytes sent via SQL*Net to client                            
      53148  bytes received via SQL*Net from client                      
       4798  SQL*Net roundtrips to/from client                           
          0  sorts (memory)                                              
          0  sorts (disk)                                                
      71947  rows processed     
--添加hint使帶有order by字句的查詢強制走index fast full scan,
但是注意cast情況還是和index full scan大致相同                                        
SQL> select /*+ index_ffs(test3 idx_test3_id) */ object_id from test3 order by o
bject_id;

已選擇71947行。


執行計劃
----------------------------------------------------------
Plan hash value: 1094006042

--------------------------------------------------------------------------------
--------------
| Id  | Operation             | Name         | Rows  | Bytes |TempSpc| Cost (%CP
U)| Time     |
--------------------------------------------------------------------------------
--------------
|   0 | SELECT STATEMENT      |              | 71947 |   351K|       |   267   (
2)| 00:00:04 |
|   1 |  SORT ORDER BY        |              | 71947 |   351K|   856K|   267   (
2)| 00:00:04 |
|   2 |   INDEX FAST FULL SCAN| IDX_TEST3_ID | 71947 |   351K|       |    45   (
0)| 00:00:01 |
--------------------------------------------------------------------------------
--------------


統計信息
----------------------------------------------------------
         48  recursive calls
          0  db block gets
        175  consistent gets
          1  physical reads
          0  redo size
     843616  bytes sent via SQL*Net to client
      53148  bytes received via SQL*Net from client
       4798  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
      71947  rows processed
     
SQL> select /*+ index_ffs(test3 idx_test3_id) */ object_id from test3;

已選擇71947行。


執行計劃
----------------------------------------------------------               
Plan hash value: 1226029696                                              
                                                                         
-------------------------------------------------------------------------------------                                                                                               
| Id  | Operation            | Name         | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                               
-------------------------------------------------------------------------------------                                                                                               
|   0 | SELECT STATEMENT     |              | 71947 |   351K|    45   (0)| 00:00:01 |                                                                                               
|   1 |  INDEX FAST FULL SCAN| IDX_TEST3_ID | 71947 |   351K|    45   (0)| 00:00:01 |                                                                                               
-------------------------------------------------------------------------------------                                                                                               


統計信息
----------------------------------------------------------               
          1  recursive calls                                             
          0  db block gets                                               
       4953  consistent gets                                             
          0  physical reads                                              
          0  redo size                                                   
     843616  bytes sent via SQL*Net to client                            
      53148  bytes received via SQL*Net from client                      
       4798  SQL*Net roundtrips to/from client                           
          0  sorts (memory)                                              
          0  sorts (disk)                                                
      71947  rows processed                                              

SQL> alter system flush buffer_cache;

系統已更改。

SQL> select /*+ index_ffs(test3 idx_test3_id) */ object_id from test3;

已選擇71947行。


執行計劃
----------------------------------------------------------               
Plan hash value: 1226029696                                              
                                                                         
-------------------------------------------------------------------------------------                                                                                               
| Id  | Operation            | Name         | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                               
-------------------------------------------------------------------------------------                                                                                               
|   0 | SELECT STATEMENT     |              | 71947 |   351K|    45   (0)| 00:00:01 |                                                                                               
|   1 |  INDEX FAST FULL SCAN| IDX_TEST3_ID | 71947 |   351K|    45   (0)| 00:00:01 |                                                                                               
-------------------------------------------------------------------------------------                                                                                               


統計信息
----------------------------------------------------------               
          0  recursive calls                                             
          0  db block gets                                               
       4953  consistent gets                                             
        161  physical reads                                              
          0  redo size                                                   
     843616  bytes sent via SQL*Net to client                            
      53148  bytes received via SQL*Net from client                      
       4798  SQL*Net roundtrips to/from client                           
          0  sorts (memory)                                              
          0  sorts (disk)                                                
      71947  rows processed                                              
--使用hint,提示走全表掃描
SQL> select /*+ full(test3) */ object_id from test3;

已選擇71947行。


執行計劃
----------------------------------------------------------               
Plan hash value: 3306317399                                              
                                                                         
---------------------------------------------------------------------------                                                                                                         
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                         
---------------------------------------------------------------------------                                                                                                         
|   0 | SELECT STATEMENT  |       | 71947 |   351K|   280   (1)| 00:00:04 |                                                                                                         
|   1 |  TABLE ACCESS FULL| TEST3 | 71947 |   351K|   280   (1)| 00:00:04 |                                                                                                         
---------------------------------------------------------------------------                                                                                                         


統計信息
----------------------------------------------------------               
          1  recursive calls                                             
          0  db block gets                                               
       5760  consistent gets                                             
       1025  physical reads                                              
          0  redo size                                                   
     843616  bytes sent via SQL*Net to client                            
      53148  bytes received via SQL*Net from client                      
       4798  SQL*Net roundtrips to/from client                           
          0  sorts (memory)                                              
          0  sorts (disk)                                                
      71947  rows processed                                              
                                        
--執行count(*)則會走index fast full scan
SQL> select count(*) from test3;


執行計劃
----------------------------------------------------------               
Plan hash value: 2224805646                                              
                                                                         
------------------------------------------------------------------------------                                                                                                      
| Id  | Operation             | Name         | Rows  | Cost (%CPU)| Time     |                                                                                                      
------------------------------------------------------------------------------                                                                                                      
|   0 | SELECT STATEMENT      |              |     1 |    45   (0)| 00:00:01 |                                                                                                      
|   1 |  SORT AGGREGATE       |              |     1 |            |          |                                                                                                      
|   2 |   INDEX FAST FULL SCAN| IDX_TEST3_ID | 71947 |    45   (0)| 00:00:01 |                                                                                                      
------------------------------------------------------------------------------                                                                                                      


統計信息
----------------------------------------------------------               
          1  recursive calls                                             
          0  db block gets                                               
        167  consistent gets                                             
          0  physical reads                                              
          0  redo size                                                   
        345  bytes sent via SQL*Net to client                            
        392  bytes received via SQL*Net from client                      
          2  SQL*Net roundtrips to/from client                           
          0  sorts (memory)                                              
          0  sorts (disk)                                                
          1  rows processed                                              
--添加hint,強制走index full scan
SQL> select /*+ index(test3 idx_test3_id) */ count(*) from test3;


執行計劃
----------------------------------------------------------               
Plan hash value: 2484012340                                              
                                                                         
-------------------------------------------------------------------------
| Id  | Operation        | Name         | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |              |     1 |   160   (0)| 00:00:02 |
|   1 |  SORT AGGREGATE  |              |     1 |            |          |
|   2 |   INDEX FULL SCAN| IDX_TEST3_ID | 71947 |   160   (0)| 00:00:02 |
-------------------------------------------------------------------------


統計信息
----------------------------------------------------------               
          1  recursive calls                                             
          0  db block gets                                               
        160  consistent gets                                             
          0  physical reads                                              
          0  redo size                                                   
        345  bytes sent via SQL*Net to client                            
        392  bytes received via SQL*Net from client                      
          2  SQL*Net roundtrips to/from client                           
          0  sorts (memory)                                              
          0  sorts (disk)                                                
          1  rows processed                                              

SQL> spool off
--總結:
--1、按索引順序查詢的一定會走index full scan,因爲他是按照索引的順序single I/O操作來完成的,即一塊一塊的讀取。
--2、輸出結果不需要是有序的則會走index fast full scan,因爲這樣他的效率會更高一些,
oracle是執行的multiple I/O操作來完成的,一次讀取多個數據塊,讀取個數由參數db_file_multiblock_read_count來決定的

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章