|
|
|
|
公众号矩阵

1.2.3.2.5 索引跳跃式扫描

《基于Oracle的SQL优化》第1章Oracle里的优化器,本章会详细介绍与Oracle数据库里优化器相关的基础知识,目的是希望通过这一章的介绍,让大家对Oracle数据库里的优化器有一个全局、概要性的认识,打好基础,为阅读后续章节扫清障碍。本节为大家介绍索引跳跃式扫描。

作者:崔华来源:电子工业出版社|2013-12-11 18:55

1.2.3.2.5  索引跳跃式扫描

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

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

我们来看一个索引跳跃式扫描的实例。创建一个测试表EMPLOYEE:

  1. SQL> create table employee(gender varchar2(1),employee_id number);  
  2.  
  3. Table created  

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

  1. SQL> alter table employee modify(employee_id not null);  
  2.  
  3. Table altered  

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

  1. SQL> create index idx_employee on employee(gender,employee_id);  
  2.  
  3. Index created  

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

  1. begin  
  2. for i in 1..5000 loop  
  3. insert into employee values ('F',i);  
  4. end loop;  
  5. commit;  
  6. end;  
  7. /  
  8.  
  9. begin  
  10. for i in 5001..10000 loop  
  11. insert into employee values ('M',i);  
  12. end loop;  
  13. commit;  
  14. end;  
  15. /  

然后我们来看如下的范例SQL 9:

  1. select * from employee   
  2. where employee_id = 100;  

对于范例SQL 9而言,其where条件是"employee_id = 100",即它只对复合B树索引IDX_EMPOLYEE的第二列EMPLOYEE_ID指定了查询条件,但并没有对该索引的前导列GENDER指定任何查询条件。这种情况下Oracle在执行范例SQL 9时是否能用上索引IDX_EMPOLYEE呢?

我们现在来执行范例SQL 9:

  1. SQL> set autotrace traceonly  
  2. SQL> select * from employee where employee_id = 100;  

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

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

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

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

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

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

16招轻松掌握PPT技巧

16招轻松掌握PPT技巧

GET职场加薪技能
共16章 | 晒书包

289人订阅学习

20个局域网建设改造案例

20个局域网建设改造案例

网络搭建技巧
共20章 | 捷哥CCIE

645人订阅学习

WOT2019全球人工智能技术峰会

WOT2019全球人工智能技术峰会

通用技术、应用领域、企业赋能三大章节,13大技术专场,60+国内外一线人工智能精英大咖站台,分享人工智能的平台工具、算法模型、语音视觉等技术主题,助力人工智能落地。
共50章 | WOT峰会

0人订阅学习

读 书 +更多

PHP和MySQL Web开发(原书第3版)

本书将介绍如何创建可交互的Web站点,包括从最简单的订单表单到复杂的安全电子商务站点。而且,读者还将了解如何使用开放源代码技术来实现...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客