当前位置: > 数据库 > Oracle >

INDEX FULL SCAN和INDEX FAST FULL SCAN的区别

时间:2016-05-29 02:42来源:linux.it.net.cn 作者:IT
关于INDEX FULL SCAN和INDEX FAST FULL SCAN的区别在于,前者在对索引进行扫描的时候会考虑大索引的结构,而且会按照索引的排序,
    而后者则不会,INDEX FAST FULL SCAN不会去扫描根块和分支块,对索引像访问堆表一样访问,所以这两个扫描方式用在不同的场合
    如果存在ORDER BY这样的排序,INDEX FULL SCAN是合适的,如果不需要排序,那INDEX FAST FULL SCAN效率是更高的。
    试验如下:
   
   
    SQL> drop table t;

Table dropped

SQL>
SQL> CREATE TABLE t (
  2    id NUMBER,
  3    n1 NUMBER,
  4    n2 NUMBER,
  5    pad VARCHAR2(4000),
  6    CONSTRAINT t_pk PRIMARY KEY (id)
  7  );

Table created
SQL> execute dbms_random.seed(0)

PL/SQL procedure successfully completed
SQL> INSERT INTO t
  2  SELECT rownum AS id,
  3         1+mod(rownum,251) AS n1,
  4         1+mod(rownum,251) AS n2,
  5         dbms_random.string('p',255) AS pad
  6  FROM dual
  7  CONNECT BY level <= 10000
  8  ORDER BY dbms_random.value;

10000 rows inserted
SQL> CREATE INDEX t_n1_i ON t (n1);

Index created

SQL>
SQL> BEGIN
  2    dbms_stats.gather_table_stats(
  3      ownname          => user,
  4      tabname          => 'T',
  5      estimate_percent => 100,
  6      method_opt       => 'for all columns size skewonly',
  7      cascade          => TRUE
  8    );
  9  END;
10  /

PL/SQL procedure successfully completed

建立试验环境完成
  一、语句需要排序的情况
  1、使用INDEX FULL SCAN
 
  SQL> explain plan for
  2  SELECT /*+ index(t t_n1_i) gather_plan_statistics */
  3   n1
  4    FROM t
  5   WHERE n1 IS NOT NULL
  6   ORDER BY n1;

Explained

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1041622781
---------------------------------------------------------------------------
| Id  | Operation        | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT |        | 10000 | 40000 |    27  (19)| 00:00:01 |
|*  1 |  INDEX FULL SCAN | T_N1_I | 10000 | 40000 |    27  (19)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("N1" IS NOT NULL)

13 rows selected
可以看到这里执行计划并没有SORT出现
2、强制使用INDEX FAST FULL SCAN
SQL> explain plan for
  2  SELECT /*+ index_ffs(t t_n1_i) */ n1 FROM t WHERE n1 IS NOT NULL order by n1;

Explained

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3958789139
--------------------------------------------------------------------------------
| Id  | Operation             | Name   | Rows  | Bytes |TempSpc| Cost (%CPU)| Ti
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |        | 10000 | 40000 |       |    45  (36)| 00
|   1 |  SORT ORDER BY        |        | 10000 | 40000 |   248K|    45  (36)| 00
|*  2 |   INDEX FAST FULL SCAN| T_N1_I | 10000 | 40000 |       |     7  (43)| 00
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("N1" IS NOT NULL)

14 rows selected
可以清楚的看到这里出现SORT,大量的COST出现在SORT这里,
所以排序的情况INDEX FULL SCAN优于INDEX FAST FULL SCAN。
二、没有排序的情况
我们只需要去掉最后ORDER BY 就OK了
1、使用INDEX FULL SCAN
SQL> explain plan for
  2  SELECT /*+ index(t t_n1_i) */ n1 FROM t WHERE n1 IS NOT NULL;

Explained

SQL>  select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1041622781
---------------------------------------------------------------------------
| Id  | Operation        | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT |        | 10000 | 40000 |    27  (19)| 00:00:01 |
|*  1 |  INDEX FULL SCAN | T_N1_I | 10000 | 40000 |    27  (19)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("N1" IS NOT NULL)

13 rows selected
可以看到这里根本没有变化,所以排序与否(ASC,如果是DESC会稍有变化)对执行计划没有影响
2、使用INDEX FAST FULL SCAN
SQL> explain plan for
  2  SELECT /*+ index_ffs(t t_n1_i) */ n1 FROM t WHERE n1 IS NOT NULL;

Explained

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 263832501
-------------------------------------------------------------------------------
| Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |        | 10000 | 40000 |     7  (43)| 00:00:01 |
|*  1 |  INDEX FAST FULL SCAN| T_N1_I | 10000 | 40000 |     7  (43)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("N1" IS NOT NULL)

13 rows selected
没有出现SORT代价小了很多。
所以证明了我所说的。



(责任编辑:IT)
------分隔线----------------------------