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