使用索引快速全扫描(Index FFS)避免全表扫描的若干场景

使用索引快速全扫描(Index FFS)避免全表扫描(FTS)

(文档 ID 70135.1)

什么使用使用Index FFS比FTS好?

Oracle 8的Concept手册中介绍:

1. 索引必须包含所有查询中参考到的列。

2. Index FFS只能通过CBO(Index hint强制使用CBO)获得。

3. Index FFS使用hint:/*+ INDEX_FFS() */。

Index FFS是在7.3中引入的。在Oracle 7中,它要求初始化参数V733_PLANS_ENABLED的值需要是TRUE。

Index FFS将会扫描索引的全部块。返回的数据不会存储。Index FFS能够使用多块IO读,可以并行执行,就像全表扫描那样。

实例

使用Oracle 8.0.5中标准的emp和dept表(可以使用UTLSAMPL.SQL创建),不建立任何表的统计数据或索引。使用autotrace产生执行计划。

准备工作:创建一个复合索引

create index emp_ix on emp(empno, deptno, ename);

查询单个表,查询出索引的全部列:

SQL> select /*+ INDEX_FFS (emp emp_ix) */ empno, deptno, ename from emp;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=4 Card=21 Bytes=693)
   1    0   INDEX (FAST FULL SCAN) OF 'EMP_IX' (NON-UNIQUE) (Cost=4 Ca
          rd=21 Bytes=693)

查询单个表,索引列放在select或where子句中:

SQL>  select /*+ INDEX_FFS (emp emp_ix) */ empno, ename from emp
      where deptno > :bind1;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=4 Card=2 Bytes=66)
   1    0   INDEX (FAST FULL SCAN) OF 'EMP_IX' (NON-UNIQUE) (Cost=4 Ca
          rd=2 Bytes=66)

查询索引的所有列,以及不再索引中的列:

SQL> select /*+ INDEX_FFS (emp emp_ix) */ empno, ename from emp
     where deptno > :bind1 and sal <:bind2;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=1 Card=1 Bytes=46)
   1    0   TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=1 Bytes=46)

注意:CBO选择FTS,因为Index FFS不能满足查询所有列。

查询复合索引中的部分列:

SQL> select /*+ INDEX_FFS (emp emp_ix) */  ename from emp;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=4 Card=21 Bytes=147)
   1    0   INDEX (FAST FULL SCAN) OF 'EMP_IX' (NON-UNIQUE) (Cost=4 Ca
          rd=21 Bytes=147)

注意:如果查询中是索引列的子集,仍会选择Index FFS。

包含join的查询;

SQL> select  /*+ INDEX_FFS ( e emp_ix) */  e.ename, d.dname
     from emp e , dept d
     where e.deptno=d.deptno;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=6 Card=4 Bytes=168)
   1    0   HASH JOIN (Cost=6 Card=4 Bytes=168)
   2    1     INDEX (FAST FULL SCAN) OF 'EMP_IX' (NON-UNIQUE) (Cost=4
          Card=21 Bytes=420)
   3    1     TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=21 Bytes=462)
时间: 2024-07-29 06:05:20

使用索引快速全扫描(Index FFS)避免全表扫描的若干场景的相关文章

SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析

在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index Scan))呢?是否所有情况都是如此?又该如何优化呢? 下面我们通过一些简单的例子来分析理解这些现象.下面的实验环境为SQL SERVER 2008,如果在不同版本有所区别,欢迎指正.   堆表单索引 首先我们构建我们测试需要实验环境,具体情况如下所示: DROP TABLE TEST    CRE

Sql Server之旅——第二站 理解万恶的表扫描

原文:Sql Server之旅--第二站 理解万恶的表扫描 很久以前我们在写sql的时候,最怕的一件事情就是sql莫名奇妙的超级慢,慢的是撸一管子回来,那个小球还在一直转...这个着急也只有当事人才 明白,后来听说有个什么"评估执行计划",后来的后来才明白应该避免表扫描... 一:表扫描 1.现象 "表扫描"听起来很简单,不就是一行一行的扫嘛,你要说"执行计划"的话,我也会玩,为了更可观,我build一个表,再插入三行数据,如下图:   上面的P

深入理解Sql Server中的表扫描_MsSql

很久以前我们在写sql的时候,最怕的一件事情就是sql莫名奇妙的超级慢,慢的是撸一管子回来,那个小球还在一直转...这个着急也只有当事人才明白,后来听说有个什么"评估执行计划",后来的后来才明白应该避免表扫描... 一:表扫描 1.现象 "表扫描"听起来很简单,不就是一行一行的扫嘛,你要说"执行计划"的话,我也会玩,为了更可观,我build一个表,再插入三行数据,如下图:   上面的Person我是一个索引都没建,然后where一下,看看表扫描是

深入理解Sql Server中的表扫描

很久以前我们在写sql的时候,最怕的一件事情就是sql莫名奇妙的超级慢,慢的是撸一管子回来,那个小球还在一直转...这个着急也只有当事人才明白,后来听说有个什么"评估执行计划",后来的后来才明白应该避免表扫描... 一:表扫描 1.现象 "表扫描"听起来很简单,不就是一行一行的扫嘛,你要说"执行计划"的话,我也会玩,为了更可观,我build一个表,再插入三行数据,如下图: 上面的Person我是一个索引都没建,然后where一下,看看表扫描是啥样

关于Oracle 9i 跳跃式索引扫描(Index Skip Scan)的小测试

oracle|索引 在Oracle9i中我们知道能够使用跳跃式索引扫描(Index Skip Scan).然而,能利用跳跃式索引扫描的情况其实是有些限制的. 从Oracle的文档中我们可以找到这样的话: Index Skip ScansIndex skip scans improve index scans by nonprefix columns. Often, scanning index blocks is faster than scanning table data blocks.Sk

@dbsnake-用合适的函数索引来避免看似无法避免的全表扫描

昨天听了@dbsnake的SQL方法论,感觉比第一次要更有感觉,希望对实际工作能有帮助. 昨天讲到一处利用reverse函数建立索引,避免全表扫描的case,颇有感触,拿出来试一下. SQL> create table rev (id number, name varchar2(5)); Table created. SQL> select * from rev;         ID NAME ---------- -----          1 abc          2 bc    

Oracle 全表扫描及其执行计划(full table scan)

    全表扫描是Oracle访问数据库表是较为常见的访问方式之一.很多朋友一看到SQL语句执行计划中的全表扫描,就要考虑对其进行修理一番.全表扫描的存在,的确存在可能优化的余地.但事实上很多时候全表扫描也并非是最低效的,完全要看不同的情形与场合,任一方式都是有利有弊的,也就是具体情况要具体分析.本文描述了什么是全表扫描以及何时发生全表扫描,何时全表扫描才低效.  本文涉及到的相关链接:     高水位线和全表扫描      启用 AUTOTRACE 功能     Oracle 测试常用表BIG

MongoDB Primary 为何持续出现 oplog 全表扫描?

线上某 MongoDB 复制集实例(包含 Primary.Secondary.Hidden 3个节点 ),Primary 节点突然 IOPS 很高,调查后发现,其中 Hidden 处于 RECOVERING 状态,同时 Priamry 上持续有一全表扫描 oplog 的操作,正是这个 oplog 的 COLLSCAN 导致IO很高. 2017-10-23T17:48:01.845+0800 I COMMAND [conn8766752] query local.oplog.rs query: {

SQL中WHERE变量IS NULL条件导致全表扫描问题的解决方法_MsSql

复制代码 代码如下: SET @SQL = 'SELECT * FROM Comment with(nolock) WHERE 1=1    And (@ProjectIds Is Null or ProjectId = @ProjectIds)    And (@Scores is null or Score =@Scores)' 印象中记得,以前在做Oracle开发时,这种写法是会导致全表扫描的,用不上索引,不知道Sql Server里是否也是一样呢,于是做一个简单的测试1.建立测试用的表结