日期:2014-05-16  浏览次数:20484 次

【Oracle优化笔记】访问索引的方法

索引唯一性扫描(INDEX UNIQUE SCAN)(针对unique index的扫描)比索引范围扫描(INDEX UNIQUE SCAN)需要的逻辑读至少少1,这是因为索引唯一行扫描明确只有最多一行数据返回,而索引范围扫描则可能有多行数据返回,得到第一行数据之后还会向下至少再扫一个叶子节点。

 

索引全扫描(INDEX FULL SCAN):索引全扫描不需要扫描该索引的所有分支块,oracle在做索引全扫描的时候只需要访问必要的分支块的定位到位于该索引最左边的叶子块的第一行索引行,通过叶子块之间的双向指针链表就可以互相访问了。因为是按照从左至右进行扫描的,所以索引全扫描得到的数据是排好序的。索引全扫描一般都是不回表的,例如select count(*) from table; select empno from emp;能做索引全扫描的一个条件就是目标索引至少有一个索引键值列的属性是not null

 

索引快速全扫描(INDEX FAST FULL SCAN):和索引全扫描差不多,一般也是不回表的,但也有很多区别。

和索引全扫描的区别是:

索引快速全扫描只有在CBO中能用

索引全扫描不能并行执行,而索引快速全扫描既可以使用多块读也可以使用并行执行。

索引快速全扫描的结果并不一定是有序的。因为索引快速全扫描时Oracle是根据索引行在磁盘上的物理存储位置来扫描的,而不是根据索引行的逻辑顺序扫描的。

 

 

索引跳跃式扫描(INDEX SKIP SCAN):适合所有类型的复合B树索引,(包括唯一性索引和非唯一性索引),它使得那些在where条件中没有针对目标索引的前导列指定查询条件同时又对该索引的非前导列制定了查询条件的目标SQL依然能够使用该索引。 

例如索引建在(gender,eno)两列,where条件中没有gender条件只有例如emp=100这种查询条件依然可以使用该复合B树索引。

之所以能用是因为oracle帮我们对sql语句进行了改写,将前导列加了进来。

原语句:

select * from test where eno=100;

如果此时gender列只有两个取值FMoracle会帮我们把它改写成

select * form test where gender='F' and eno=100

union all

select * from test where gender='M' and eno=100;

从此可以看出oracle中的索引跳跃式扫描只适用于那些目标索引前导列的distinct值数量较少,后续非前导列的可选择性又非常好的情形,因为索引