Oracle 索引基本原理(2)

只有在表中每一行值都非NULL或是使用alter table命令的default子句时,才可以为列设置NOT NULL属性.
 alter table emp modify (sal not null);
 
 create table p(id int,nameid number(4) default 10);
 insert into p values(1,NULL);
 insert into p values(2,20);
 显示:
 ID  NAMEID
 1 
 2  20
 创建表时对列指定NOT NULL或default 可以帮助避免出现的性能问题.
 
 3.使用LIKE
 条件中有LIKE关键字会使用索引。
 通常有两种写法 LIKE '%some%'  或LIKE 'some%'
 当%在前面的时候,索引不会被使用,但是当值在%前面时候,oracle可以使用索引

4.使用函数
 除非使用基于函数的索引,否则在SQL语句的where子句中对存在的索引的列使用函数时,优化器会忽略索引.一般常见的索引如:TRUNC,SUBSTR,TO_DATE,TO_CHAR和INSTR等。
 例如下面的就会使用全表扫描
 select empno,ename,deptno from emp where trunc(hiredate)='01-MAY-01';
 改成下面的就可以了
 select empno,ename,deptno from emp where hiredate > '01-MAY-01' and hiredate < (TO_DATE('01-MAY-01') + 0.99999);
 通过改变所比较的列上的值,而不用改变列本身,就可以启用索引,这样可避免全表扫描.

5.比较不匹配的数据类型
 一种很难解决的性能问题是比较不匹配的数据类型。oracle不但不会对那些不兼容的数据类型报错,反而会做隐式数据转换。例如:oracle可以隐式得转换varchar2类型的列中的数据去匹配数值类型数据。
 如果account_number列是varchar2数据类型,下面将进行全表扫描
 select bank_name,address,city,state,zip from banks where account_number=99999;
 oracle会自动转换成 to_number(account_number) = 99999; 这样就抑制了索引的使用.

如果上面的语句加上单引号就会使用索引了
 select bank_name,address,city,state,zip from banks where account_number='99999';

五.选择性
oracle基于查询和数据,提供了多种方法来判断使用索引的价值。首先判断索引中的唯一键或不同键的数量。可以通过对表或索引进行分析的方法来确定不同键的数量,之后就可以查询USER_INDEXES视图的DISTINCT_KEYS列来查看分析结果。比较一下不同键的数量和表中的行数(USER_INDEXES视图中的NUM_ROWS),就可以知道索引的选择性.索引的选择性越高意味着一个索引值返回的行数就越少,该索引就越好。
 索引的选择性可以帮助基于成本的优化器来决定执行路径.

六.集群因子
集群因子是索引与它所在的表相比较的有序性度量,它用于检查在索引访问之后执行的表查找的成本。
如果具有较大的集群因子,就必须访问更多的表数据块才可以获得每个索引块中对应的数据行。
如果集群因子接近于表中的数据块数量,就表示索引对应数据行的排序情况良好;但是集群因子接近于表中的数据行数量,就表示索引对应的数据块排序情况不佳。
 集群因子计算简要:
 1.按顺序扫描索引
 2.将当前索引值指向的ROWID的数据块部分与前一个索引值指向的数据块进行比较(比较索引中的邻近行)
 3.如果ROWID指向该表中不同的数据块,就增加集群因子(对整个索引执行该操作)。
 CLUSTERING_FACTOR列是USER_INDEXES视图中的一列,该列反映了数据相对于已索引的列是显得有序。

七.二元高度 (Binary Height)
索引的二元高度对把ROWID返回给用户进程时所要求的IO数量起到关键作用。二元高度的每个级别都会增加一个额外的块读取操作,而且由于这些块不能按顺序读取,它们都要求一个独立的IO操作.
例如:下面的一个二元高度为3的索引,需要读4个快才能返回一行数据给用户,其中3次用来读索引.1次用来读表。随着索引的二元高度的增加,检索数据所要求的IO次数也会随之增加.
         ________
boxter  idx block id        |  |
king idx block id --->king idx block id    | |
   holman idx block id------>bolman  row id |  |
        histan  row id ------>_______|   
 level 1   level 2   level 3  表
----------------------二元高度为3的索引(level为3叶节点所在位置)---------------------


通过查询DBA_INDEXES视图的BLEVEL列来查看它的二元高度:
EXECUTE DBMS_STATS.GATHER_INDEX_STATS('SCOTT','EMP_ID1');
select blevel,index_name from dba_indexes where index_name='EMP_ID1';

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/54a351932523bfb76c2e30d845e73b6b.html