Oracle索引事理

来源:网海拾贝




Oracle供应了少量索引选项。晓得在给定前提下运用哪个选项关于一个使用递次的功能来说很是主要。一个错误的选择年夜概会引发去世锁,并招致数据库功能急剧降落或进程中缀。而若是做出准确的选择,则可以公道运用本钱,使那些曾经运转了几个小时甚至几天的进程在几分钟得以完成,这样会使您立刻成为一位豪杰。这篇文章就将庞年夜的评论冲突每个索引选项。主要有以下内容:

[1] 根基的索引观点

盘查DBA_INDEXES视图可得到表中悉数索引的列表,留意只能经过进程USER_INDEXES的方式来检索形式(schema)的索引。访问USER_IND_COLUMNS视图可得到一个给定表中被索引的特定列。

[2] 组合索引

当某个索引包孕有多个已索引的列时,称这个索引为组合(concatented)索引。在 Oracle9i引入腾跃式扫描的索引访问方式之前,盘查只能在有限前提下运用该索引。比方:表emp有一个组合索引键,该索引包孕了empno、 ename和deptno。在Oracle9i之前除非在where之句中对第一列(empno)指定一个值,不然就不克不及运用这个索引键举办一次领域扫描。

奇怪留意:在Oracle9i之前,只要在运用到索引的前导索引时才可以运用组合索引!

[3] ORACLE ROWID

经过进程每个行的ROWID,索引Oracle供应了访问单行数据的才干。ROWID真实便是间接指向独自行的线路图。若是想反省屡屡值或是其他对ROWID自己的援用,可以在任何表中运用和指定rowid列。

[4] 限定索引

限定索引是一些没有阅历的开拓人员屡屡犯的错误之一。在SQL中有很多骗局会使一些索引无法运用。下面评论冲突一些罕见的成就:
    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前提,就可以运用索引,以防止全表扫描。
     
4.2 运用IS NULL 或IS NOT NULL

运用IS NULL 或IS NOT NULL异样会限定索引的运用。因为NULL值并没有被定义。在SQL语句中运用NULL会有很多的费事。因此发起开拓人员在建表时,把需求索引的列设成NOT NULL。若是被索引的列在某些行中存在NULL值,就不会运用这个索引(除非索引是一个位图索引,关于位图索引在稍后在过细评论冲突)。

4.3 运用函数

若是不运用基于函数的索引,那么在SQL语句的WHERE子句中对存在索引的列运用函数时,会使优化器马虎失落这些索引。 下面的盘查不会运用索引(只需它不是基于函数的索引)
          select empno,ename,deptno
          from   emp
          where  trunc(hiredate)='01-MAY-81';
          把下面的语句改成下面的语句,这样就可以经过进程索引举办查找。
          select empno,ename,deptno
          from   emp
          where  hiredate<(to_date('01-MAY-81') 0.9999);
     4.4 对照不婚配的数据典范
         对照不婚配的数据典范也是对照难于发明的功能成就之一。
         留意下面盘查的例子,account_number是一个VARCHAR2典范,
         在account_number字段上有索引。下面的语句将实施全表扫描。
         select bank_name,address,city,state,zip
         from   banks
         where  account_number = 990354;
         Oracle可以自动把where子句酿成to_number(account_number)=990354,这样就限定了
          索引的运用,改成下面的盘查就可以运用索引:
         select bank_name,address,city,state,zip
         from   banks
         where  account_number ='990354';
     奇怪留意:不婚配的数据典范之间对照会让Oracle自动限定索引的运用,
        纵然对这个盘查实施Explain Plan也不克不及让您大白为什么做了一次“全表扫描”。
[5] 选择性

运用USER_INDEXES视图,该视图中表现了一个distinct_keys列。对照一下唯一键的数目和表中的行数,就可以判定索引的选择性。选择性越高,索引前往的数据就越少。

[6] 纠集因子(Clustering Factor)

Clustering Factor位于USER_INDEXES视图中。该列反响反映了数据相干于已索引的列能否显得有序。若是Clustering Factor列的值接近于索引中的树叶块(leaf block)的数目,表中的数据就越有序。若是它的值接近于表中的行数,则表中的数据就不是很有序。

[7] 二元高度(Binary height)

索引的二元高度对把ROWID前往给用户进程时所要求的I/O量起到关键感化。在对一个索引举办说明后,可以经过进程盘查DBA_INDEXES的B- level列检察它的二元高度。二元高度主要随着表的巨细以及被索引的列中值的领域的狭窄水平而变革。索引上若是有少量被删除的行,它的二元高度也会增加。更新索引列也类似于删除操作,因为它增加了已删除键的数目。重建索引年夜概会低潮二元高度。

[8] 快速全局扫描

在Oracle7.3后就可以运用快速全局扫描(Fast Full Scan)这个选项。这个选项许诺Oracle实施一个全局索引扫描操作。快速全局扫描读取B-树索引上悉数树叶块。初始化文件中的 DB_FILE_MULTIBLOCK_READ_COUNT参数可以控制同时被读取的块的数目。

[9] 腾跃式扫描

从Oracle9i初步,索引腾跃式扫描特性可以许诺优化器运用组合索引,纵然索引的前导列没有出现在WHERE子句中。索引腾跃式扫描比全索引扫描要快的多。下面的递次清单表现出功能的差别:
    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索引
     索引编排表
     反转键索引
     基于函数的索引
     分区索引
     本地和全局索引




版权声明: 原创作品,许诺转载,转载时请务必以超链接形式标明文章 原始来由 、作者信息和本声明。不然将追究司法责任。

原文地址:https://www.cnblogs.com/zgqjymx/p/1976296.html