INDEX FULL SCAN和INDEX FAST FULL SCAN的区别

关于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代价小了很多。

所以证明了我所说的。

转载于:https://my.oschina.net/sniperLi/blog/357251

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值