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

所以证明了我所说的。

时间: 2024-10-07 08:34:55

INDEX FULL SCAN和INDEX FAST FULL SCAN的区别的相关文章

index full scan 和 index fast full scan (IFS,FFS)的不同

转自ITPUB 首先来看一下IFS,FFS能用在哪里:在一句sql中,如果我们想搜索的列都包含在索引里面的话,那么index full scan 和 index fast full scan 都可以被采用代替full table scan.比如以下语句: SQL> CREATE TABLE TEST AS SELECT * FROM dba_objects WHERE 0=1; SQL> CREATE INDEX ind_test_id ON TEST(object_id); SQL>

MYSQL中的type:index 和 Extra:Using index

原创水平有限,如有错误请指出 考虑下面执行计划中的TYPE和Extra +----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  |

create index online 和create index 不同及注意点

CREATE INDEX ONLINE 锁模式变化模拟 SESSION 139 SQL>  insert into test123   2  select * from dba_objects;   50062 rows inserted 不提交 SESSION 148 SQL> create index test123_i on test123(owner) online; 回话148堵塞 SQL>  select * from v$lock where sid in ('139','

The Query Optimizer

The Query Optimizer This chapter discusses SQL processing, optimization methods, and how the query optimizer (usually called the optimizer) chooses a specific plan to execute SQL. The chapter contains the following sections: Overview of the Query Opt

Oracle 监控索引的使用率

    Oracle提供了索引监控特性来判断索引是否被使用.在Oracle 10g中,收集统计信息会使得索引被监控,在Oracle 11g中该现象不复存在.尽管如此,该方式仅提供的是索引是否被使用.索引被使用的频率未能得以体现.下面的脚本将得到索引的使用率,可以很好的度量索引的使用情况以及根据这个值来判断当前的这些索引是否可以被移除或改进.   1.索引使用频率报告 --运行环境 SQL> select * from v$version where rownum<2; BANNER -----

Oracle 监控索引使用率脚本分享_oracle

Oracle提供了索引监控特性来判断索引是否被使用.在Oracle 10g中,收集统计信息会使得索引被监控,在Oracle 11g中该现象不复存在.尽管如此,该方式仅提供的是索引是否被使用.索引被使用的频率未能得以体现.下面的脚本将得到索引的使用率,可以很好的度量索引的使用情况以及根据这个值来判断当前的这些索引是否可以被移除或改进. 1.索引使用频率报告 --运行环境 SQL> select * from v$version where rownum<2; BANNER -----------

解析10053事件

  转自http://hi.baidu.com/%C8%FD%B7%C9%D4%C6/blog/item/4bdbbb501278f565843524c1.html         你是否想知道一句sql语句如何执行,它是否走索引,是否采用不同得驱动表,是否用nestloop join,hash join-..?这一切对你是否很神秘呢?或许你会说execution plan能看到这些东西,但是你是否清楚execution plan是如何得到?这篇文章就是给出了隐藏在execution plan底

FBI? MAX? INDEX FULL SCAN (MIN/MAX)?

这个是我在comp.database.oracle.server新闻组问的问题,自己一直不知道为什么?昨天看了人家的解答,记录下来. http://jonathanlewis.wordpress.com/2007/03/12/methods/ 这个地址好像国内无法访问. March 12, 2007 Methods Filed under: Troubleshooting - Jonathan Lewis @ 9:52 pm UTC Mar 12,2007 The following quest

【每日一摩斯】-Index Skip Scan Feature (212391.1)

INDEX Skip Scan,也就是索引快速扫描,一般是指谓词中不带复合索引第一列,但扫描索引块要快于扫描表的数据块,此时CBO会选择INDEX SS的方式. 官方讲的,这个概念也好理解,如果将复合索引看做是一个分区表,其中分区主键(这里指的是复合索引的首列)定义了存储于此的分区数据.在每个键(首列)下的每行数据都将按照此键排序.因此在SS,首列可以被跳过,非首列可以作为逻辑子索引访问.因此一个"正常"的索引访问可以忽略首列. 复合索引被逻辑地切分成更小的子索引.逻辑子索引的个数取决