Oracle最常用的B树索引的5种访问方法(三)

2015-07-16 12:09:51 · 作者: · 浏览: 7
SKIP SCAN)适用所有复合B树索引。它使那些在where 条件中没有对目标索引的前导列指定查询条件但同时又对该索引的非前导列指定了查询条件的目标SQL依然可以用上该索引。这就像是在扫描索引时跳过了他的前导列,直接从该索引的非前导列开始扫描一样。
?看一个例子:
?SQL>create table test1(name varchar2(10),id number not null);
? 创建一个复合B树索引
?SQL>create index idx_naid on test1(name,id);
? 插入10000条记录,5000条name列为test,5000条name列为prot
? begin
? for i in 1..5000 loop
? insert into test1 values('test',i);
? end loop;
? commit;
? end;
? /
? begin
? for i in 1..5000 loop
? insert into test1 values('prot',i);
? end loop;
? commit;
? end;
? /
? SQL>SET AUTOTRACE TRACEONLY
? SQL>exec dbms_stats.gather_table_stats('SCOTT','TEST1',estimate_percent=>100,cascade=>true,method_opt=>'for all columns size 1');
? SQL>select * from test1 where id=200;
? Execution Plan
?----------------------------------------------------------
?Plan hash value: 4123651466


-----------------------------------------------------------------------------
?| Id? | Operation? | Name? ? | Rows? | Bytes | Cost (%CPU)| Time? ? |
?-----------------------------------------------------------------------------
?|? 0 | SELECT STATEMENT |? ? |? 2 |? 16 |? 3? (0)| 00:00:01 |
?|*? 1 |? INDEX SKIP SCAN | IDX_NAID |? 2 |? 16 |? 3? (0)| 00:00:01 |
?-----------------------------------------------------------------------------


Predicate Information (identified by operation id):
?---------------------------------------------------


? 1 - access("ID"=200)
? ? ? ? filter("ID"=200)



?Statistics
?----------------------------------------------------------
? ? 1? recursive calls
? ? 0? db block gets
? ? 7? consistent gets
? ? 0? physical reads
? ? 0? redo size
? 505? bytes sent via SQL*Net to client
? 385? bytes received via SQL*Net from client
? ? 2? SQL*Net roundtrips to/from client
? ? 0? sorts (memory)
? ? 0? sorts (disk)
? ? 2? rows processed


例子中的where条件是id=200,只对复合B树索引的第二列id指定了查询条件,并没有对索引的前导列name指定任何查询条件。这里没有指定前导列的情况下还能使用上索引,是因为oracle自动对该索引的前导列的所有distinct值做了遍历。


从例子中分析的过程看,oracle中的索引跳跃式扫描仅仅适用于那些目标索引前导列的distinct值数量较少,后续非前导列的可选择性又非常好的情况。因为索引跳跃式扫描的执行效率一定会随着目标索引前导列的distinct值数量的递增而递减。