一、什么是索引
 常见的索引有B-TREE索引、位图索引、全文索引,位图索引一般用于数据仓库应用,全文索引由于使用较少,这里不深入介绍。B-TREE索引包括很多扩展类型,如组合索引、反向索引、函数索引等等,以下是B-TREE索引的简单介绍:

 B-TREE索引也称为平衡树索引(Balance Tree),它是一种按字段排好序的树形目录结构,主要用于提升查询性能和唯一约束支持B-TREE索引的内容包括根节点、分支节点、叶子节点。B-TREE索引如下图所示:


                                                       索引_B-TREE索引

如果我们把一个表的内容认为是一本字典,那索引就相当于字典的目录,如下图所示:


                                                    索引_位图索引_02

 图中是一个字典按部首+笔划数的目录,相当于给字典建了一个按部首+笔划的组合索引。
一个表中可以建多个索引,就如一本字典可以建多个目录一样(按拼音、笔划、部首等等)。
一个索引也可以由多个字段组成,称为组合索引,如上图就是一个按部首+笔划的组合目录。


二、索引的作用:
索引是什么我们先说到这里,以后我们会进一步的讲述,索引不单是对列排序那么简单,在排序的基础上,它还按数据结构中B树的方式存储,这个就是后话了。下面我们说一下,索引有什么用。索引的作用,只有两个字,就是“查找”。它是为了加快查找速度。对于无序的一组数据,想在其中查找某一个数,只能逐个进行对比。而在有序的数列中查找某一个数,则有许多种方法,比如折半查找等等,ORACLE采用的是B树法。通常在表中某一列搜索数据时,如果此列上建立的有索引,ORACLE会自动的在索引中利用搜索算法,快速的找到要查找的值,再取出对应行的行地址,根据此行地址一表中取出行数据。这个速度比没有索引时要快很多倍。
下面,我们先建立一个索引,仍后试一下使用索引查找数据,比不用索引时速度到底有什么不同。


三、索引的创建
索引的创建语法:CREATE INDEX 索引名 ON 表名(列1,列2,……)
索引可以按照一个表的多个列创建,这样的索引称为复合索引。对于复合索引,ORACLE先按列1排序,如果列1的值有重复的,再按列2排序,等等。
下面我先创建一个比较大一点的表,行数多一点,这样我们对比通过索引查找和无索引时的查找,它们间的差别更明显。


gyj@OCM> drop table t5;


Table dropped.


gyj@OCM> create table t5 as select * from dba_objects;


Table created.


我通过DBA_OJECTS表,创建T5表。DBA_OBJECTS表存储数据库中所有对象的相关信息,行比较多。但是这样行还是不够多


gyj@OCM> insert into t5 select * from t5;


72804 rows created.


gyj@OCM> /


145608 rows created.


gyj@OCM> /


291216 rows created.


gyj@OCM> /


582432 rows created.


gyj@OCM> commit;


Commit complete.


 我再如上将T5中的行读出来,插入到T5中,反复几次,让T5表的行数至少有一百万行左右。
gyj@OCM>  select count(*) from t5;


  COUNT(*)
----------
   1164864


最终,我的T5表中的100多万行。
然后,我们打开ORACLE的计数器:


gyj@OCM> set timing on   
gyj@OCM> select * from t5 where object_name='T5';
(结果略)
Elapsed: 00:00:00.25


用时0.25秒。因为ORACLE会在内存中缓存一些信息,因此,上面的命令,应该多执行几次,等待每次执行时间没有太大的变化,取这个执行时间稳定下来的结果,这样比较准确。我这里,没有建索引时,用时0.15秒。
因为是在OBJECT_NAME列查找,我就在OBJECT_NAME列上,建立一个索引:


gyj@OCM> create index idx_t5_object_name on t5(object_name);


Index created.


创建索引的命令,非常简单,我就不再说了。下面我已经以T5表的OBJECT_NANE列为准,创建了索引,通常说我为T5表的OBJECT_NAME列创建了索引,下面再次在这个列中进行查询,


gyj@OCM> select * from t5 where object_name='T5';
(结果略)
Elapsed: 00:00:00.01


当每次的执行时间稳定下来后,当有索引后,执行时间是0.01秒。
执行时间有非常明显的下降,而且,随着表中行数的进一步增加,按索引搜索和直接在表中搜索所耗时间,差距会更大。使用索引进行查找的优势,会更明显。
索引的使用是透明的,在这条“select * from t5 where object_name='T5'”语句中,我们完全看不到有索引的影子,只要“WHERE 条件”所涉及的列,创建有对应的索引,ORACLE会自动的选择使用索引。
由于索引对于加快查找速度有显著效果,我们可以在经常需要查找的列上,都创建索引。但是索引的数量也不适合太多。因为每一个索引都会有相应的索引维护操作。你每在表中插入一行,ORACLE会将相应列的值,插入进索引。每删除一行,或修改索引对应列的值,ORACLE也都要对应的修改索引。在对表进行DML时,所引起的对索引的DML操作,就是索引维护。它加重了DML操作时的负担,因此,索引是不适合建太多的,否则,DML操作时的速度将更慢。


四、基于函数的索引
我们仍以刚才的例子为准,在OBJECT_NAME列上有索引。下面,我们试一下如下命令:
gyj@OCM> select * from t5 where lower(object_name)='t5';
(结果省略)
Elapsed: 00:00:00.64


它的稳定时间,是0.64秒左右。虽然我们的条件仍然涉及到了OBJECT_NAME列,但上面的命令显然没有使用索引。因为它的执行时间很慢。在使用索引查找时,速度只有0.01秒左右。现在是0.64秒。没有使用索引的原因是这语句的条件:lower(object_name)='t5' ,先把OBEJCT_NAME转为了小写,再和小写的t5比较。一旦像这样对列名进行了处理,索引将不会被使用。如果经常要对此列转换为小写再比较,为了使用索引,你可以专门创建“基于函数的索引”,命令如下:


gyj@OCM> create index idx_f_t5_obname on t5(lower(object_name));


Index created.


和上面创建普通索引的命令基本相同,只是将列名换为了LOWER(列) ,好,下面再试查询的速度有没有提高:


gyj@OCM> select * from t5 where lower(object_name)='t5';
(结果省略)
Elapsed: 00:00:00.01


稳定耗时是00: 00: 00.01 。0.01秒,比没有基于函数索引前的0.64秒快了很多倍。
这就是基于函数的索引。


五、索引创建指南

这是一个非常复杂的话题,需要对业务及数据充分分析后再能得出结果。主键及外键通常都要有索引,其它需要建索引的字段应满足以下条件,如下图所示:

                                                           索引_B-TREE索引_03

 1、字段的选择性很好(主键最佳)。
 2、字段出现在查询条件中,并且查询条件可以使用索引。
 3、语句执行频率高,一天会有几千次以上。
 4、通过字段条件可筛选的记录集很小。


六、删除索引
索引会带来额外的索引维护操作,因此,不经常使用的索引,我们应该及时的删除它,以减少DML操作时的负担。删除索引命令如下,把上面刚建的基于函数的索引删掉:


gyj@OCM> drop index idx_f_t5_obname;                    


Index dropped.





**********本博客所有内容均为原创,如有转载请注明作者和出处!!!**********
Name:    guoyJoe

QQ:        252803295

Email:    oracledba_cn@hotmail.com

Blog:      http://blog.csdn.net/guoyJoe

ITPUB:   http://www.itpub.net/space-uid-28460966.html

OCM:     http://education.oracle.com/education/otn/YGuo.HTM
 _____________________________________________________________
加群验证问题:哪些SGA结构是必需的,哪些是可选的?否则拒绝申请!!!

答案在:http://blog.csdn.net/guoyjoe/article/details/8624392

Oracle@Paradise  总群:127149411

Oracle@Paradise No.1群:177089463(已满)

Oracle@Paradise No.2群:121341761

Oracle@Paradise No.3群:140856036