Fast Full Index Scans的特點!

warehouse發表於2008-04-13

其實Fast Full Index Scans是針對full table scan而言的,Fast Full Index Scans的一些特點也和full table scan相似(如:多塊讀):

Fast Full Index Scans的一些特點:

1.Fast full scan is available only with the CBO

2.at least one column in the index key has the NOT NULL constraint

3. A fast full scan accesses the data in the index itself, without accessing the table

4.It cannot be used to eliminate a sort operation, because the data is not ordered by the index key.(粗略的試驗了一下發現也是排好序了,按照index_key)

5.It reads the entire index using multiblock reads, unlike a full index scan

6.Fast full index scans cannot be performed against bitmap indexes(這裡有點問題,在10g,11g下測似沒有問題啊)

7.A fast full scan is faster than a normal full index scan in that it can use multiblock I/O and can be parallelized just like a table scan

8.There must be a parallel clause on the index if you want to perform a fast full index scan in parallel. The parallel degree of the index is set independently. The index does not inherit the degree of parallelism of the table.

9.You must have analyzed the index; otherwise, the optimizer might decide not to use it

[@more@]

SQL> create index idx_tt on tt(id);

索引已建立。

SQL> select /*+ index_ffs(a idx_tt) */ id from tt a;

ID
----------
6
0
1
2
3
4
5

已選擇7行。


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

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 28 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| TT | 14 | 28 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------


統計資訊
----------------------------------------------------------
1 recursive calls
0 db block gets
8 consistent gets
0 physical reads
0 redo size
491 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
7 rows processed

SQL> desc tt
名稱 是否為空? 型別
----------------------------------------- -------- ----------------------------

ID NUMBER(38)
NAME VARCHAR2(10)
AGE NUMBER(38)

--在index_column上至少有一列存在not null constraint
SQL> alter table tt modify id not null;

表已更改。

SQL> select id from tt ;

ID
----------
0
1
2
3
4
5
6

已選擇7行。


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

---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 28 | 1 (0)| 00:00:01 |
| 1 | INDEX FULL SCAN | IDX_TT | 14 | 28 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------


統計資訊
----------------------------------------------------------
194 recursive calls
0 db block gets
32 consistent gets
0 physical reads
0 redo size
491 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
7 rows processed

SQL> create bitmap index idx_tt on tt(id);

索引已建立。

SQL> select /*+ index_ffs(tt idx_tt) */ id from tt ;

ID
----------
0
1
2
3
4
5
6

已選擇7行。


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

--------------------------------------------------------------------------------

-------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Tim

e |

--------------------------------------------------------------------------------

-------

| 0 | SELECT STATEMENT | | 14 | 28 | 1 (0)| 00:

00:01 |

| 1 | BITMAP CONVERSION TO ROWIDS | | 14 | 28 | 1 (0)| 00:

00:01 |

| 2 | BITMAP INDEX FAST FULL SCAN| IDX_TT | | | |
|

--------------------------------------------------------------------------------

-------

統計資訊
----------------------------------------------------------
1 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
491 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
7 rows processed

SQL>
BITMAP INDEX FAST FULL SCAN和INDEX FAST FULL SCAN是不是一回事?
--================================================
SQL> drop index idx_tt;

索引已刪除。

SQL> create index idx_tt on tt(id) parallel 2;

索引已建立。

SQL> select index_name,degree from user_indexes where index_name='IDX_TT';

INDEX_NAME DEGREE
------------------------------ ----------------------------------------
IDX_TT 2

SQL> select /*+ index_ffs(tt idx_tt) */ id from tt ;

ID
----------
0
1
2
3
4
5
6

已選擇7行。


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

--------------------------------------------------------------------------------

---------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
| TQ |IN-OUT| PQ Distrib |

--------------------------------------------------------------------------------

---------------------------------

| 0 | SELECT STATEMENT | | 14 | 28 | 2 (0)| 00:00:

01 | | | |

| 1 | PX COORDINATOR | | | | |
| | | |

| 2 | PX SEND QC (RANDOM) | :TQ10000 | 14 | 28 | 2 (0)| 00:00:

01 | Q1,00 | P->S | QC (RAND) |

| 3 | PX BLOCK ITERATOR | | 14 | 28 | 2 (0)| 00:00:

01 | Q1,00 | PCWC | |

| 4 | INDEX FAST FULL SCAN| IDX_TT | 14 | 28 | 2 (0)| 00:00:

01 | Q1,00 | PCWP | |

--------------------------------------------------------------------------------

---------------------------------

統計資訊
----------------------------------------------------------
27 recursive calls
3 db block gets
15 consistent gets
0 physical reads
716 redo size
491 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
7 rows processed

SQL>
--===================================================================
按照id確實排序了!並沒有象doc上說的不排序,還有待於驗證!
SQL> insert into tt select *from tt;

已建立7行。

SQL> commit;

提交完成。

SQL> select /*+ index_ffs(tt idx_tt) */ id from tt ;

ID
----------
0
0
1
1
2
2
3
3
4
4
5

ID
----------
5
6
6

已選擇14行。


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

--------------------------------------------------------------------------------

---------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
| TQ |IN-OUT| PQ Distrib |

--------------------------------------------------------------------------------

---------------------------------

| 0 | SELECT STATEMENT | | 14 | 28 | 2 (0)| 00:00:

01 | | | |

| 1 | PX COORDINATOR | | | | |
| | | |

| 2 | PX SEND QC (RANDOM) | :TQ10000 | 14 | 28 | 2 (0)| 00:00:

01 | Q1,00 | P->S | QC (RAND) |

| 3 | PX BLOCK ITERATOR | | 14 | 28 | 2 (0)| 00:00:

01 | Q1,00 | PCWC | |

| 4 | INDEX FAST FULL SCAN| IDX_TT | 14 | 28 | 2 (0)| 00:00:

01 | Q1,00 | PCWP | |

--------------------------------------------------------------------------------

---------------------------------

統計資訊
----------------------------------------------------------
6 recursive calls
0 db block gets
14 consistent gets
0 physical reads
0 redo size
526 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
14 rows processed

SQL>
--=========================================================================================
測試使用db_file_multiblock_read_count的效果並不明顯,隨著db_file_multiblock_read_count的減小應該看到物理讀有明顯的增多才是,可是並沒有看到物理讀有顯著的變化。
SQL> alter table t modify object_id not null;

表已更改。

SQL> set time on
10:41:42 SQL> set time off
SQL> set timing on
SQL> set autotrace off
SQL> set autotrace on
SQL> select count(object_id) from t;

COUNT(OBJECT_ID)
----------------
2019072

已用時間: 00: 00: 01.57

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1188 (2)| 00:00:15 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 1188 (2)| 00:00:15 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
206 recursive calls
0 db block gets
4376 consistent gets
4335 physical reads
0 redo size
430 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> select count(object_id) from t;

COUNT(OBJECT_ID)
----------------
2019072

已用時間: 00: 00: 00.34

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1188 (2)| 00:00:15 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 1188 (2)| 00:00:15 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
0 recursive calls
0 db block gets
4346 consistent gets
0 physical reads
0 redo size
430 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> show parameter mul

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_file_multiblock_read_count integer 43
parallel_adaptive_multi_user boolean TRUE
SQL> alter session set db_file_multiblock_read_count=8;

會話已更改。

已用時間: 00: 00: 00.00
SQL> show parameter mul

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_file_multiblock_read_count integer 8
parallel_adaptive_multi_user boolean TRUE

SQL> alter system flush shared_pool;

系統已更改。

SQL> alter system flush buffer_cache;

系統已更改。

已用時間: 00: 00: 00.21
SQL> select count(object_id) from t;

COUNT(OBJECT_ID)
----------------
2019072

已用時間: 00: 00: 02.46

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1188 (2)| 00:00:15 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 1188 (2)| 00:00:15 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
309 recursive calls
0 db block gets
4391 consistent gets
4349 physical reads
0 redo size
430 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> select count(object_id) from t;

COUNT(OBJECT_ID)
----------------
2019072

已用時間: 00: 00: 00.28

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1188 (2)| 00:00:15 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 1188 (2)| 00:00:15 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
0 recursive calls
0 db block gets
4346 consistent gets
0 physical reads
0 redo size
430 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> alter system flush shared_pool;

系統已更改。

已用時間: 00: 00: 00.37

SQL> alter system flush buffer_cache;

系統已更改。

已用時間: 00: 00: 00.21
SQL> select count(object_id) from t;

COUNT(OBJECT_ID)
----------------
2019072

已用時間: 00: 00: 02.46

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1188 (2)| 00:00:15 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 1188 (2)| 00:00:15 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
309 recursive calls
0 db block gets
4391 consistent gets
4349 physical reads
0 redo size
430 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> select count(object_id) from t;

COUNT(OBJECT_ID)
----------------
2019072

已用時間: 00: 00: 00.28

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1188 (2)| 00:00:15 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 1188 (2)| 00:00:15 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
0 recursive calls
0 db block gets
4346 consistent gets
0 physical reads
0 redo size
430 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> alter session set db_file_multiblock_read_count=4;

會話已更改。

已用時間: 00: 00: 00.00
SQL> alter system flush shared_pool;

系統已更改。

已用時間: 00: 00: 00.64
SQL> alter system flush buffer_cache;

系統已更改。

已用時間: 00: 00: 00.75
SQL> select count(object_id) from t;

COUNT(OBJECT_ID)
----------------
2019072

已用時間: 00: 00: 01.89

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1639 (1)| 00:00:20 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 1639 (1)| 00:00:20 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
313 recursive calls
0 db block gets
4391 consistent gets
4349 physical reads
0 redo size
430 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> alter session set db_file_multiblock_read_count=2;

會話已更改。

已用時間: 00: 00: 00.01
SQL> alter system flush shared_pool;

系統已更改。

已用時間: 00: 00: 00.81
SQL> alter system flush buffer_cache;

系統已更改。

已用時間: 00: 00: 00.07
SQL> select count(object_id) from t;

COUNT(OBJECT_ID)
----------------
2019072

已用時間: 00: 00: 02.35

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2540 (1)| 00:00:31 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 2540 (1)| 00:00:31 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
313 recursive calls
0 db block gets
4391 consistent gets
4349 physical reads
0 redo size
430 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> alter session set db_file_multiblock_read_count=1;

會話已更改。

已用時間: 00: 00: 00.01
SQL> alter system flush shared_pool;

系統已更改。

已用時間: 00: 00: 00.48
SQL> alter system flush buffer_cache;

系統已更改。

已用時間: 00: 00: 00.06
SQL> select count(object_id) from t;

COUNT(OBJECT_ID)
----------------
2019072

已用時間: 00: 00: 03.06

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4341 (1)| 00:00:53 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 4341 (1)| 00:00:53 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
313 recursive calls
0 db block gets
4391 consistent gets
4349 physical reads
0 redo size
430 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
1 rows processed

SQL>
--================================================================================
試驗證明確實只有在cbo下可以使用fast full index scan
SQL> alter session set optimizer_mode=choose;

會話已更改。

已用時間: 00: 00: 00.03
SQL> select count(*) from t;

COUNT(*)
----------
2019072

已用時間: 00: 00: 01.62

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 963 (2)| 00:00:12 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2019K| 963 (2)| 00:00:12 |
-----------------------------------------------------------------------


統計資訊
----------------------------------------------------------
1 recursive calls
0 db block gets
4346 consistent gets
4239 physical reads
0 redo size
422 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> analyze table t delete statistics ;

表已分析。

已用時間: 00: 00: 00.32
SQL> analyze index idx_t delete statistics ;

索引已分析

已用時間: 00: 00: 00.03
SQL> select count(*) from t;

COUNT(*)
----------
2019072

已用時間: 00: 00: 07.68

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

-----------------------------------
| Id | Operation | Name |
-----------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT AGGREGATE | |
| 2 | TABLE ACCESS FULL| T |
-----------------------------------

Note
-----
- rule based optimizer used (consider using cbo)


統計資訊
----------------------------------------------------------
1 recursive calls
0 db block gets
27227 consistent gets
27217 physical reads
0 redo size
422 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
--有無statistics不重要,並不像doc說的You must have analyzed the index; otherwise, the optimizer might decide not to use it,重要的是optimizer_mode必須是cbo支援的模式才行。

SQL> alter session set optimizer_mode=all_rows;

會話已更改。

已用時間: 00: 00: 00.00
SQL> select count(*) from t;

COUNT(*)
----------
2019072

已用時間: 00: 00: 01.43

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

-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 969 (1)| 00:00:12 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_T | 2086K| 969 (1)| 00:00:12 |
-----------------------------------------------------------------------

Note
-----
- dynamic sampling used for this statement


統計資訊
----------------------------------------------------------
28 recursive calls
0 db block gets
4432 consistent gets
497 physical reads
0 redo size
422 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL>

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/19602/viewspace-1002468/,如需轉載,請註明出處,否則將追究法律責任。

相關文章