zoukankan      html  css  js  c++  java
  • 索引跳跃式扫描(INDEX SKIP SCAN)

    索引跳跃式扫描(INDEX SKIP SCAN)

    索引跳跃式扫描(INDEX SKIP SCAN)适用于所有类型的复合B树索引(包括唯一性索引和非唯一性索引),它使那些在where条件中没有对目标索引的前导列指定查询条件但同时又对该 索引的非前导列指定了查询条件的目标SQL依然可以用上该索引,这就像是在扫描该索引时跳过了它的前导列,直接从该索引的非前导列开始扫描一样(实际的执行过程并非如此),这也是索引跳跃式扫描中"跳跃"(SKIP)一词的含义。

    为什么在where条件中没有对目标索引的前导列指定查询条件但Oracle依然可以用上该索引呢?这是因为Oracle帮你对该索引的前导列的所有distinct值做了遍历。

    实例

    创建一个测试表EMPLOYEE:

    create table employee(gender varchar2(1),employee_id number);

    将该表的列EMPLOYEE_ID的属性设为NOT NULL:

    alter table employee modify(employee_id not null);

    创建一个名为IDX_EMPOLYEE的复合B树索引,其中列GENDER是该索引的前导列,列EMPLOYEE_ID是该索引的第二列:

    create index idx_employee on employee(gender,employee_id);

    使用如下PL/SQL代码往表EMPLOYEE中插入10,000条记录,其中5,000条记录的列GENDER的值为"F",另外5,000条记录的列GENDER的值为"M":

    begin
    
    for i in 1..5000 loop
    
    insert into employee values ('F',i);
    
    end loop;
    
    commit;
    
    end;
    
    begin
    
    for i in 5001..10000 loop
    
    insert into employee values ('M',i);
    
    end loop;
    
    commit;
    
    end;

    对表EMPLOYEE 及索引收集一下统计信息:

    analyze table EMPLOYEE compute statistics for table for all columns for all indexes;

    执行以下sql

    select * from employee where employee_id = 100;

    where条件是"employee_id = 100",即它只对复合B树索引IDX_EMPOLYEE的第二列EMPLOYEE_ID指定了查询条件,但并没有对该索引的前导列GENDER指定任何查询条件。

    set autotrace traceonly  
    
    select * from employee where employee_id = 100;

    执行计划如下:

    从上述显示内容可以看出,Oracle在执行时用上了索引IDX_EMPOLYEE,并且其执行计划走的就是对该索引的索引跳跃式扫描。

    这里在没有指定前导列的情况下还能用上述索引,就是因为Oracle帮我们对该索引的前导列的所有distinct值做了遍历。

    所谓的对目标索引的所有distinct值做遍历,其实际含义相当于对原目标SQL做等价改写(即把要用的目标索引的所有前导列的distinct 值都加进来)。索引IDX_EMPOLYEE的前导列GENDER的distinct值只有"F"和"M"两个值,所以这里能使用索引 IDX_EMPOLYEE的原因可以简单地理解成是Oracle将范例SQL 9等价改写成了如下形式:

    select * from employee where gender = 'F' and employee_id = 100 
    union all  
    select * from employee where gender = 'M' and employee_id = 100;

    结论

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

  • 相关阅读:
    TP生成二维码插件
    day23 常用模块(中)
    day22 作业
    day22 常用模块(上)
    day21 模块与包+软件开发目录规范
    day20 作业
    day20 函数收尾+面向过程+模块
    day19 作业
    day19 生成器+函数递归
    day18 作业
  • 原文地址:https://www.cnblogs.com/zjpeng/p/10766795.html
Copyright © 2011-2022 走看看