您的位置:首页 > 数据库 > Oracle

深入浅出oracle索引

2019-04-10 00:42 127 查看

1,索引结构的推理

索引由root(根块),branch(茎块)和leaf(叶子块)三部分组成,其中leaf(叶子块)主要存储key column value(索引列具体值),以及能具体定位到数据块所在位置的rowid(注意区分数据块和索引块)。

有一张test表,该表大致有name(varchar2(20)),id(number),height(number),age(number)等字段。当前该表有记录,我们要对test表的id列建索引,即create index idx_id on test(id);执行这个动作后,会发生哪些变化呢?

1,要建索引先排序

未建索引的test表大致记录如下图所示,null表示该字段为空值,此外省略号表示略去不显示的内容。注意rowid伪列,这个是每一行的唯一标识,每一行的rowid值绝对不重复,由它可定位到行的记录在数据库中的位置。

name age height id 伪列
小余 ...... ...... 100000 rowid
老张 ...... ...... 5 rowid
老王 ...... ...... 3 rowid
小马 ...... ...... 1 rowid
大刘 ...... ...... 4 rowid
小明

......

......   rowid
小黄 ...... ...... 2 rowid
老李 ...... ...... 7 rowid
...... ...... ...... ...... ......
...... ...... ...... 6 ......

建索引后,先从test表的id列由小到大顺序取出数据放到内存中(这里要注意,除了id列的值外,还要注意取该列值的同时,该行的rowid也一并取出)。

                                                        

2,列值入块成索引

一次将内存中顺序存放的列值和对应的rowid存进oracle空闲的block中,形成索引块,具体如下图所示:

                                                                    

3,填满一块又一块

随着索引列的值不断插入,index block(L1)很快就被插满了,比如接下来取出的id=9的记录将无法插入index block(L1)中,只有插入到新的oracle块中,如下图所示的index block2(L2)。与此同时,发生了一件非常重要的事情,就是写新数据到另一个块index block3(B1),这是为啥呢?原来L1和L2平起平坐,谁都不服谁,于是index block3(B1)就负担起管理IDE角色,这个block记录了L1和L2的信息,并不记录具体的索引列的键值,目前只占用了B1的一点点空间。具体细节如下:

                                          

4,同级两块需人管

随着叶子块的不断增加,B1快中虽然仅存放叶子块的标记,但也挡不住量大,最终也容纳不下了。就到下一个B2块中寻找空间容纳。这时B1和B2也平起平坐了,谁都不服谁。接着,最上层的root根块就诞生了。后续还会出现B3,B4,。。。如果有一天,这些Bn把root块撑满了,root块就不是root块了,它也要被人管着,它额的上面又有了领导了。

通过上面的4个步骤,索引的结构是什么样子,终于可以一清二楚了。

2,索引特性的提炼

通过上述的索引结构推论,我们其实可以得出非常重要,非常实用的三大特性:

1,索引高度低

首先我们从上往下看,最底层的叶子块index block因为装具体额的数据,所以比较容易被填满,特别是对长度很长的列建索引时更是如此。但是第一层之上的第二层的index block就很不容易装满了吧,因为第二层只是装第一层的指针而已,而第三层装第二层的index block的指针,更不容易被填满了。

2,索引存储列值

接下来我们从里往外看,我们很清楚,索引块就是存放索引的列值以及对应的rowid,这里的rowid也是非常重要的,要想通过定位到的索引信息再返回到表中查到具体的其他列值信息,还非得靠这个rowid。

3,索引本身有序

最后我们从左往右看,可以发现索引是按顺序从表里取出数据,再按顺序插入到块里形成索引块的。所以说索引块是有序的。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: