Oracle中组合索引

INDEX SKIP SCAN是9i之后提供的新功能,实现了即使WHERE条件中不存在索引的前导列也可以使用索引。但是INDEX SKIP SCAN是需要下面几个条件的:
1,版本9i及以后
2,CBO(表和索引都经过分析)
3,索引的前导列重复值很少(选择性低)
4,WHERE条件中不存在索引前导列
举例:
1,    建立测试环境
Sql>select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for IBM/AIX RISC System/6000: Version 10.2.0.1.0 - Productio
NLSRTL Version 10.2.0.1.0 - Production
Sql>conn sunwg/test
已连接
Sql>create table sunwg as select * from dba_objects;
表已创建
Sql>create index ind_type_id on sunwg(object_type,object_id);
索引已创建

3,一般情况下,WHERE条件中包含索引的前导列,那么查询是会选择索引的
 
4,如果WHERE中不包括索引的前导列,在没有统计信息的情况下,优化器是不会选择索引的。
 
5,收集了表和索引的统计信息,那么就会执行索引的跳跃扫描
 
从两次执行时候的COST可以看得出来,执行索引跳跃扫描的时候效率会比全表扫描高不少。索引跳跃扫描具体是怎么执行的呢?
从网上查了资料,说是索引跳跃扫描实际上转化成为多个SQL的UNION操作,对于上面的例子,可能大概转化为下面的形式:
Select * from sunwg where object_type = ‘TABLE’ and object_id = 68191
Union
Select * from sunwg where object_type = ‘INDEX’ and object_id =68191
Union
……
我们有验证这种说法的正确性,但是利用这种说法可以很好的解释为什么索引跳跃扫描仅仅发生在前导列的重复值很多的情况下。因为如果索引前导列的重复值很少,那么将会转化成大量SQL的UNION操作,这样效率相对来说会低得多。
上面就是大家经常的对索引跳跃扫描的理解,觉得索引跳跃扫描相比全表扫描来说有着更好的性能。但是很少想到,索引跳跃扫描真是很好的事情么?
从两方面来说吧
1,    当前导列的重复值很多的时候,ORACLE并不会选择索引的跳跃扫描,他认为这样的效率设置比全表扫描还要低。可是实际上,ORACLE并没有把第二索引列考虑进去,如果第二个索引列的选择性很高的情况下,走索引可能还是一种高效的访问方式。实验很简单,这里就不做了,感兴趣的可以自己实验下。
2,    前面说过了,只有前导列的重复值很小的时候,ORACLE才会选择索引跳跃扫描。其实索引跳跃扫描仅仅是对低效索引的一种弥补。从B+树索引的结构可以看得出来,索引列的选择性越高那么索引的效果越好。那么在建多列索引中的时候也应该把选择性高的列放到前面,这样可以极大的提高的索引访问的效率。所以当我们的SQL 走了索引跳跃扫描的时候,我们应该多想想是不是我们的索引建立的有问题。
ORACLE新版本的一些新的特性,有一些是原来没有东西,有一些是对原有的有问题的东西的修补,那么我们在使用新特性的时候要多想想,多比比,这样才可以合理的使用那些新的东西。

在Oracle中可以创建组合索引,即同时包含两个或两个以上列的索引。在组合索引的使用方面,Oracle有以下特点:

    1、 当使用基于规则的优化器(RBO)时,只有当组合索引的前导列出现在SQL语句的where子句中时,才会使用到该索引;

    2、 在使用Oracle9i之前的基于成本的优化器(CBO)时, 只有当组合索引的前导列出现在SQL语句的where子句中时,才可能会使用到该索引,这取决于优化器计算的使用索引的成本和使用全表扫描的成本,Oracle会自动选择成本低的访问路径(请见下面的测试1和测试2);

    3、 从Oracle9i起,Oracle引入了一种新的索引扫描方式——索引跳跃扫描(index skip scan),这种扫描方式只有基于成本的优化器(CBO)才能使用。这样,当SQL语句的where子句中即使没有组合索引的前导列,并且索引跳跃扫描的成本低于其他扫描方式的成本时,Oracle就会使用该方式扫描组合索引(请见下面的测试3);

    4、 Oracle优化器有时会做出错误的选择,因为它再“聪明”,也不如我们SQL语句编写人员更清楚表中数据的分布,在这种情况下,通过使用提示(hint),我们可以帮助Oracle优化器作出更好的选择(请见下面的测试4)。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值