在关系数据库中,索引是一种与表有关的数据库结构,它可使对应于表的SQL语句执行得更快。索引的做用至关于图书的目录,能够根据目录中的页码快速找到所需的内容。 数据库
对于数据库来讲,索引是一个必选项,但对于如今的各类大型数据库来讲,索引能够大大提升数据库的性能,以致于它变成了数据库不可缺乏的一部分。oracle
索引分类:函数
逻辑分类性能
single column or concatenated 对一列或多列建所引ui
unique or nonunique 惟一的和非惟一的所引,也就是对某一列或几列的键值(key)是不是惟一的。spa
Function-based 基于某些函数索引,当执行某些函数时须要对其进行计算,能够将某些函数的计算结果事先保存并加以索引,提升效率。 翻译
Doman 索引数据库之外的数据,使用相对较少指针
物理分类code
B-Tree :normal or reverse key B-Tree索引也是咱们传统上常见所理解的索引,它又能够分为正常所引和倒序索引。orm
Bitmap : 位图所引,后面会细讲
B-Tree 索引
B-Tree index 也是咱们传统上常见所理解的索引。B-tree (balance tree)即平衡树,左右两个分支相对平衡。
B-Tree index
Root为根节点,branch 为分支节点,leaf 到最下面一层称为叶子节点。每一个节点表示一层,当查找某一数据时先读根节点,再读支节点,最后找到叶子节点。叶子节点会存放index entry (索引入口),每一个索引入口对应一条记录。
Index entry 的组成部分:
Indexentry entry header 存放一些控制信息。
Key column length 某一key的长度
Key column value 某一个key 的值
ROWID 指针,具体指向于某一个数据
建立索引:
conn as1 dex (id ,sex (),name ( i .. dex (i,, SQL dex_idx1 ,object_type DEX
索引分离于表,做为一个单独的个体存在,除了能够根据单个字段建立索引,也能够根据多列建立索引。Oracle要求建立索引最多不可超过32列。
SQL> create index dex_index2 on dex(sex,name);Index created. SQL> select object_name,object_type from user_objects;OBJECT_NAME OBJECT_TYPE--------------------------------------------------------------------------------DEX TABLEDEX_IDX1 INDEXDEX_INDEX2 INDEX
这里须要理解:
编写一本书,只有章节页面定好以后再设置目录;数据库索引也是同样,只有先插入好数据,再创建索引。那么咱们后续对数据库的内容进行插入、删除,索引也须要随之变化。但索引的修改是由oracle自动完成的。
上面这张图能更加清晰的描述索引的结构。
跟节点记录0至50条数据的位置,分支节点进行拆分记录0至10.......42至50,叶子节点记录每第数据的长度和值,并由指针指向具体的数据。
最后一层的叶子节是双向连接,它们是被有序的连接起来,这样才能快速锁定一个数据范围。
如:
SQL> select * from dex where id>23 and id<32; ID SE NAME---------- -- -------------------- 24 M chongshi 25 M chongshi 26 M chongshi 27 M chongshi 28 M chongshi 29 M chongshi 30 M chongshi 31 M chongshi8 rows selected.
如上面查找的列子,经过索引的方式先找到第23条数据,再找到第32条数据,这样就能快速的锁定一个查找的范围,若是每条数据都要从根节点开始查找的话,那么效率就会很是低下。
位图索引
位图索引主要针对大量相同值的列而建立。拿全国居民登陆一第表来讲,假设有四个字段:姓名、性别、年龄、和身份证号,年龄和性别两个字段会产生许多相同的值,性别只有男女两种值,年龄,1到120(假设最大年龄120岁)个值。那么无论一张表有几亿条记录,但根据性别字段来区分的话,只有两种取值(男、女)。那么位图索引就是根据字段的这个特性所创建的一种索引。
Bitmap Index
从上图,咱们能够看出,一个叶子节点(用不一样颜色标识)表明一个key , start rowid 和 end rowid规定这种类型的检索范围,一个叶子节点标记一个惟一的bitmap值。由于一个数值类型对应一个节点,当时行查询时,位图索引经过不一样位图取值直接的位运算(与或),来获取到结果集合向量(计算出的结果)。
举例讲解:
假设存在数据表T,有两个数据列A和B,取值以下,咱们看到A和B列中存在相同的数据。
对两个数据列A、B分别创建位图索引:idx_t_bita和idx_t_bitb。两个索引对应的存储逻辑结构以下:
Idx_t_bita索引结构,对应的是叶子节点:
Idx_t_bitb索引结构,对应的是叶子节点:
对查询“select * from t where b=1 and (a=’L’ or a=’M’)”
分析:位图索引使用方面,和B*索引有很大的不一样。B*索引的使用,一般是从根节点开始,通过不断的分支节点比较到最近的符合条件叶子节点。经过叶子节点上的不断Scan操做,“扫描”出结果集合rowid。
而位图索引的工做方式大相径庭。经过不一样位图取值直接的位运算(与或),来获取到结果集合向量(计算出的结果)。
针对实例SQL,能够拆分红以下的操做:
一、a=’L’ or a=’M’
a=L:向量:1010
a=M:向量:0001
or操做的结果,就是两个向量的或操做:结果为1011。
二、结合b=1的向量
中间结果向量:1011
B=1:向量:1001
and操做的结果,1001。翻译过来就是第一和第四行是查询结果。
三、获取到结果rowid
目前知道了起始rowid和终止rowid,以及第一行和第四行为操做结果。能够经过试算的方法获取到结果集合rowid。
位图索引的特色:
1.Bitmap索引的存储空间节省
2.Bitmap索引建立的速度快
3.Bitmap索引容许键值为空
4.Bitmap索引对表记录的高效访问
建立位图索引:
查看表记录 SQL> select * from dex; ................... ID SEX NAME---------- -- -------------------- 991 M chongshi 992 M chongshi 993 G chongshi 994 G chongshi 995 G chongshi 996 M chongshi 997 G chongshi 998 G chongshi 999 G chongshi 1000 M chongshi1000 rows selected. 对于上面表来讲sex(性别)只有两种值,最适合用来建立位图所引 建立索引: SQL> create bitmap index my_bit_idx on dex(sex);Index created. 查看建立的所引 SQL> select object_name,object_type from user_objects;OBJECT_NAME OBJECT_TYPE--------------------------------------------------------------------------------MY_BIT_IDX INDEX
建立索引的一些规则
1、权衡索引个数与DML之间关系,DML也就是插入、删除数据操做。
这里须要权衡一个问题,创建索引的目的是为了提升查询效率的,但创建的索引过多,会影响插入、删除数据的速度,由于咱们修改的表数据,索引也要跟着修改。这里须要权衡咱们的操做是查询多仍是修改多。
二、把索引与对应的表放在不一样的表空间。
当读取一个表时表与索引是同时进行的。若是表与索引和在一个表空间里就会产生资源竞争,放在两个表这空就可并行执行。
三、最好使用同样大小是块。
Oracle默认五块,读一次I/O,若是你定义6个块或10个块都须要读取两次I/O。最好是5的整数倍更能提升效率。
四、若是一个表很大,创建索引的时间很长,由于创建索引也会产生大量的redo信息,因此在建立索引时能够设置不产生或少产生redo信息。只要表数据存在,索引失败了大不了再建,因此能够不须要产生redo信息。
五、建索引的时候应该根据具体的业务SQL来建立,特别是where条件,还有where条件的顺序,尽可能将过滤大范围的放在后面,由于SQL执行是从后往前的。(小李飛菜刀)
索引常见操做
改变索引:
SQL> alter index employees_last _name_idx storage(next 400K maxextents 100);
索引建立后,感受不合理,也能够对其参数进行修改。详情查看相关文档
调整索引的空间:
新增长空间 SQL> alter index orders_region_id_idx allocate extent (size 200K datafile '/disk6/index01.dbf'); 释放空间 SQL> alter index oraers_id_idx deallocate unused;
索引在使用的过程当中可能会出现空间不足或空间浪费的状况,这个时候须要新增或释放空间。上面两条命令完成新增与释放操做。关于空间的新增oracle能够自动帮助,若是了解数据库的状况下手动增长能够提升性能。
从新建立索引:
所引是由oracle自 动完成,当咱们对数据库频繁的操做时,索引也会跟着进行修改,当咱们在数据库中删除一条记录时,对应的索引中并无把相应的索引只是作一个删除标记,但它 依然占据着空间。除非一个块中全部的标记全被删除的时,整个块的空间才会被释放。这样时间久了,索引的性能就会降低。这个时候能够从新创建一个干净的索引 来提升效率。
SQL> alter index orders_region_id_idx rebuild tablespace index02;
经过上面的命令就能够重现创建一个索引,oracle重创建索引的过程:
一、锁表,锁表以后其余人就不能对表作任何操做。
二、建立新的(干净的)临时索引。
三、把老的索引删除掉
四、把新的索引从新命名为老索引的名字
五、对表进行解锁。
移动所引:
其实,咱们移动索引到其它表空间也一样使用上面的命令,在指定表空间时指定不一样的表空间。新的索引建立在别位置,把老的干掉,就至关于移动了。
SQL> alter index orders_region_id_idx rebuild tablespace index03;
在线从新建立索引:
上面介绍,在建立索引的时候,表是被锁定,不能被使用。对于一个大表,从新建立索引所须要的时间较长,为了知足用户对表操做的需求,就产生的这种在线从新建立索引。
SQL> alter index orders_id_idx rebuild online;
建立过程:
一、锁住表
二、建立立临时的和空的索引和IOT表用来存在on-going DML。普通表存放的键值,IOT所引表直接存放的表中数据;on-gong DML也就是用户所作的一些增删改的操做。
三、对表进行解锁
四、从老的索引建立一个新的索引。
五、IOT表里存放的是on-going DML信息,IOT表的内容与新建立的索引合并。
六、锁住表
七、再次将IOT表的内容更新到新索引中,把老的索引干掉。
八、把新的索引从新命名为老索引的名字
九、对表进行解锁
整合索引碎片:
如上图,在不少索引中有剩余的空间,能够经过一个命令把剩余空间整合到一块儿。
SQL> alter index orders_id_idx coalesce;
删除索引:
SQL> drop index hr.departments_name_idx;
分析索引
检查所引的有效果,前面介绍,索引用的时间久了会产生大量的碎片、垃圾信息与浪费的剩余空间了。能够经过从新建立索引来提升所引的性能。
能够经过一条命令来完成分析索引,分析的结果会存放在在index_stats表中。
查看存放分析数据的表: SQL> select count(*) from index_stats; COUNT(*)---------- 0执行分析索引命令: SQL> analyze index my_bit_idx validate structure;Index analyzed. 再次查看 index_stats 已经有了一条数据 SQL> select count(*) from index_stats; COUNT(*)---------- 1把数据查询出来: SQL> select height,name,lf_rows,lf_blks,del_lf_rows from index_stats; HEIGHT NAME LF_ROWS LF_BLKS DEL_LF_ROWS---------- ---------------------------------------------------------------------- ---------- ----------- 2 MY_BIT_IDX 1000 3 100
分析数据分析:
(HEIGHT)这个所引高度是2 ,(NAME)索引名为MY_BIT_IDX ,(LF_ROWS)所引表有1000行数据,(LF_BLKS)占用3个块,(DEL_LF_ROWS)删除100条记录。
这里也验证了前面所说的一个问题,删除的100条数据只是标记为删除,由于总的数据条数依然为1000条,占用3个块,那么每一个块大于333条记录,只有删除的数据大于333条记录,这时一个块被清空,总的数据条数才会减小。