柔中带刚,刚中带柔,淫荡中富含柔和,刚猛中荡漾风骚,无坚不摧,无孔不入!
全部博文(1669)
分类: Oracle
2011-12-13 16:50:49
Oracle提供了大量索引选项。知道在给定条件下使用哪个选项对于一个应用程序的性能来说非常重要。一个错误的选择可能会引发死锁,并导致数据库性能急剧下降或进程终止。而如果做出正确的选择,则可以合理使用资源,使那些已经运行了几个小时甚至几天的进程在几分钟得以完成,这样会使您立刻成为一位英雄。这篇文章就将简单的讨论每个索引选项。主要有以下内容: 网管u家u.bitsCN.com [1] 基本的索引概念 中国网管论坛bbs.bitsCN.com 查询DBA_INDEXES视图可得到表中所有索引的列表,注意只能通过USER_INDEXES的方法来检索模式(schema)的索引。访问USER_IND_COLUMNS视图可得到一个给定表中被索引的特定列。 网管联盟bitsCN_com [2] 组合索引 网管u家 当某个索引包含有多个已索引的列时,称这个索引为组合(concatented)索引。在 Oracle9i引入跳跃式扫描的索引访问方法之前,查询只能在有限条件下使用该索引。比如:表emp有一个组合索引键,该索引包含了empno、 ename和deptno。在Oracle9i之前除非在where之句中对第一列(empno)指定一个值,否则就不能使用这个索引键进行一次范围扫描。 网管网
中国网管论坛bbs.bitsCN.com [3] ORACLE ROWID 网管下载dl.bitscn.com 通过每个行的ROWID,索引Oracle提供了访问单行数据的能力。ROWID其实就是直接指向单独行的线路图。如果想检查重复值或是其他对ROWID本身的引用,可以在任何表中使用和指定rowid列。 中国网管论坛bbs.bitsCN.com [4] 限制索引 网管联盟
4.1 使用不等于操作符(<>、!=) 下面的查询即使在cust_rating列有一个索引,查询语句仍然执行一次全表扫描。 select cust_Id,cust_name from customers where cust_rating <> 'aa'; 把上面的语句改成如下的查询语句,这样,在采用基于规则的 优化器而不是基于代价的优化器(更智能)时,将会使用索引。 select cust_Id,cust_name from customers where cust_rating < 'aa' or cust_rating > 'aa'; 特别注意:通过把不等于操作符改成OR条件,就可以使用索引,以避免全表扫描。 中国网管论坛bbs.bitsCN.com
使用IS NULL 或IS NOT NULL同样会限制索引的使用。因为NULL值并没有被定义。在SQL语句中使用NULL会有很多的麻烦。因此建议开发人员在建表时,把需要索引的列设成 NOT NULL。如果被索引的列在某些行中存在NULL值,就不会使用这个索引(除非索引是一个位图索引,关于位图索引在稍后在详细讨论)。 网管bitscn_com 4.3 使用函数 网管联盟bitsCN_com 如果不使用基于函数的索引,那么在SQL语句的WHERE子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。 下面的查询不会使用索引(只要它不是基于函数的索引) 网管联盟bitsCN_com
[5] 选择性 网管网www_bitscn_com 使用USER_INDEXES视图,该视图中显示了一个distinct_keys列。比较一下唯一键的数量和表中的行数,就可以判断索引的选择性。选择性越高,索引返回的数据就越少。 网管联盟bitsCN_com [6] 群集因子(Clustering Factor) 中国网管联盟bitsCN.com
网管网 [7] 二元高度(Binary height) 网管网 索引的二元高度对把ROWID返回给用户进程时所要求的I/O量起到关键作用。在对一个索引进行分析后,可以通过查询DBA_INDEXES的B- level列查看它的二元高度。二元高度主要随着表的大小以及被索引的列中值的范围的狭窄程度而变化。索引上如果有大量被删除的行,它的二元高度也会增加。更新索引列也类似于删除操作,因为它增加了已删除键的数目。重建索引可能会降低二元高度。 网管网 [8] 快速全局扫描 网管网
[9] 跳跃式扫描 网管网www_bitscn_com 从Oracle9i开始,索引跳跃式扫描特性可以允许优化器使用组合索引,即便索引的前导列没有出现在WHERE子句中。索引跳跃式扫描比全索引扫描要快的多。下面的程序清单显示出性能的差别: 网管网www_bitscn_com create index skip1 on emp5(job,empno); index created. select count(*) from emp5 where empno=7900; Elapsed:00:00:03.13 Execution Plan 0 SELECT STATEMENT Optimizer=CHOOSE(Cost=4 Card=1 Bytes=5) 1 0 SORT(AGGREGATE) 2 1 INDEX(FAST FULL SCAN) OF 'SKIP1'(NON-UNIQUE) Statistics 6826 consistent gets 6819 physical reads select /*+ index(emp5 skip1)*/ count(*) from emp5 where empno=7900; Elapsed:00:00:00.56 Execution Plan 0 SELECT STATEMENT Optimizer=CHOOSE(Cost=6 Card=1 Bytes=5) 1 0 SORT(AGGREGATE) 2 1 INDEX(SKIP SCAN) OF 'SKIP1'(NON-UNIQUE) Statistics 21 consistent gets 17 physical reads[10] 索引的类型 B-树索引 位图索引 HASH索引 索引编排表 反转键索引 基于函数 |