索引跳跃式扫描(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值数量的递增而递减。

索引跳跃式扫描(INDEX SKIP SCAN)的更多相关文章

  1. 深入理解Oracle索引(1):INDEX SKIP SCAN 和 INDEX RANGE SCAN

    ㈠ Index SKIP SCAN                当表有一个复合索引,而在查询中有除了索引中第一列的其他列作为条件,并且优化器模式为CBO,这时候查询计划就有可能使用到SS       ...

  2. 索引唯一性扫描(INDEX UNIQUE SCAN)

           索引唯一性扫描(INDEX UNIQUE SCAN)是针对唯一性索引(UNIQUE INDEX)的扫描,它仅仅适用于where条件里是等值查询的目标SQL.因为扫描的对象是唯一性索引,所 ...

  3. 索引范围扫描(INDEX RANGE SCAN)

    索引范围扫描(INDEX RANGE SCAN)适用于所有类型的B树索引,当扫描的对象是唯一性索引时,此时目标SQL的where条件一定是范围查询(谓词条件为 BETWEEN.<.>等): ...

  4. oralce索引中INDEX SKIP SCAN 和 INDEX RANGE SCAN区别

    INDEX SKIP SCAN 当表中建立有复合索引的时候,查询时,除复合索引第一列外,别的列作为条件时,且优化器模式为CBO,这个时候查询可能会用到INDEX SKIP SCAN skip scan ...

  5. 索引快速扫描(index fast full scan)

    一.索引快速扫描(index fast full scan) 索引快速全扫描(INDEX FAST FULL SCAN)和索引全扫描(INDEX  FULL SCAN)极为类似,它也适用于所有类型的B ...

  6. index range scan,index fast full scan,index skip scan发生的条件

    源链接:https://blog.csdn.net/robinson1988/article/details/4980611 index range scan(索引范围扫描): 1.对于unique ...

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

    INDEX Skip Scan,也就是索引快速扫描,一般是指谓词中不带复合索引第一列,但扫描索引块要快于扫描表的数据块,此时CBO会选择INDEX SS的方式. 官方讲的,这个概念也好理解,如果将复合 ...

  8. INDEX SKIP SCAN适用场景

    --请记住这个INDEX SKIP SCAN扫描方式 drop table t purge;create table t as select * from dba_objects;update t s ...

  9. Index Skip Scan in Oracle in 11g

    http://viralpatel.net/blogs/oracle-index-skip-scan/ in 11g the same sql use index skip scan but in 1 ...

随机推荐

  1. Leetcode 两数之和 (散列表)

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...

  2. PTA4

    这个作业属于哪个课程 C语言程序设计2 这个作业要求在哪里 \https://edu.cnblogs.com/campus/zswxy/software-engineering-class2-2018 ...

  3. 网络操作基础(two)

    P106 一.什么是活动目录?活动目录有哪些优点? 二.什么是域.域树.森林? 三.什么是信任?什么是域的方向及传递性? 四.如何管理活动目录的信任与站点? 解答! (一) 1.活动目录:提供了用于存 ...

  4. 汇编实验一 查看CPU和内存,用机器指令和汇编语言指令编程

    在装完DosBox环境之后,就可以用debug模式进行汇编指令的编程了. 实验内容:      首先用a指令进行数据的储存,然后用t命令进行调试. 可以发现ax,bx在不同的命令下发生了改变,cs的地 ...

  5. webpack学习笔记(五)

    1. 如果想编写一个libray的库,代码结构如下: -library -src -index.js -math.js -string.js math.js export function add(a ...

  6. keepalived.conf配置说明

    vim /etc/keepalived/keepalived.conf配置信息如下! Configuration File for keepalived global_defs { notificat ...

  7. 18.9 有关设置栈指针sp寄存器r13

    为什么在调用C程序时,要在汇编(.S)文件中设置栈指针sp(Stack Pointer) r13?设置栈指针的时候赋的值是多少,如何确定? .text .global _start _start: / ...

  8. Hbase数据库

        1.简介 HBase从诞生至今将近10年,在apache基金会的孵化下,已经变成一个非常成熟的项目,也有许多不同的公司支持着许多不同的分支版本,如cloudra等等. HBase不同于一般的关 ...

  9. docker中安装ps命令

    apt-get update && apt-get install -y procps

  10. Python之print()函数

    1. 输出字符串 >>> str = 'Hello World' >>> print (str) Hello World 2. 格式化输出整数 支持参数格式化 &g ...