Oracle索引以及索引碎片

  索引,可以增加查询速度,若没有索引,每次查询都必须是全表查询。例如,搜索某个记录时(如name="gdpuzxs")时,需要全表扫描一下,因为不知道有多少个name="gdpuzxs"的记录。若在字段name上建立了索引,oracle会构建索引条目(name:rowid),每次查询,可以快速定位到这行记录。

  (1)位图索引

  oracle的索引主要有B树索引以及位图索引。这里主要总结一下B树索引,主要有根节点,分支节点,叶子节点,结构图如下:

  

  每个索引条目都是按照升序排序的(也可以指定为降序),都有两个字段(键值对),对于根节点和分支节点,第一个字段是下属节点的最小键值,第二个字段是下属节点的地址。如根节点,(0,B1;500,B2;1000,B3)代表下属有三个节点,第一个节点的索引最小值为0,地址是B1;第二节点的索引最小值为500,地址是B2,依次类推。

  对于叶节点,同样有两个字段(键值对),第一个字段也是下属节点索引的最小值,第二字段是指向数据的rowid。比如你要查找值为150的数据,首先从根节点,进行对比,0<150<500,进入B1,0<150<200,进入L1,查找到值为150相对的rowid。

  (2)索引碎片

  频繁的对索引字段进行update,delete操作,会对索引造成大量的索引碎片,从而影响索引的使用效率。

  对某个索引行执行删除操作时,只是为该行增加了一个删除标志,这个索引行不会真正的释放内存空间。当insert新的数据的时候,也不能插入到该位置。

  所以,无论是插入,删除,更新索引数据,都需要消耗储存空间,增大B-TREE索引结构的深度,影响数据的查询速度。尤其是删除和修改,不仅造成空间的浪费,也增加了扫描索引块的速度。所以,建议对经常使用的索引表进行索引重建操作。

  (3)案例分析

  (1)新建一个testIndex表并且建立索引,如下:

create table testIndex(Id int)

create index index_1  on testIndex(id)

  (2)插入100万条数据,如下:

SQL> begin
  2  for i in 1..1000000 loop
  3  insert into testIndex values(i);
  4  if mod(i,100)=0 then
  5  commit;
  6  end if;
  7  end loop;
  8  end;
  9  /

  (3)索引碎片分析

  先删除70万条数据,如下:

delete from  testindex where rownum<=700000

  创建索引分析,查询结果如下:

analyze index index_1 validate structure

select name,del_lf_rows_len,lf_rows_len,(del_lf_rows_len/lf_rows_len)*100 as "索引碎片率" from index_stats;

  

  如果索引碎片率超过30%,建议对索引进行索引碎片整理。

  (4)索引碎片整理

alter index index_1 rebuild 

    再次执行索引碎片分析:索引碎片为0。

analyze index index_1 validate structure

select name,del_lf_rows_len,lf_rows_len,(del_lf_rows_len/lf_rows_len)*100 as "索引碎片率" from index_stats;

    

  参考网址:http://blog.itpub.net/41451/viewspace-1058441/

         http://www.cnblogs.com/zhaoguan_wang/p/5169821.html

原文地址:https://www.cnblogs.com/gdpuzxs/p/6928147.html