继实现索引遇到的问题

 上一篇文章:http://blog.youkuaiyun.com/xinghongduo/article/details/8754650

 

    上一篇文章的最后尝试了取消关键字页,直接将关键字存储在索引节点中减少IO次数的办法。当时的想法还不太成熟,直接将索引节点的关键字长度直接定义为767,索引节点的阶数是固定的,但多数情况下关键字的长度也就是几十字节,大部分的空间得不到利用,IO效率低下,而且索引占用的空间也比较大。

 

    为此我做了进一步改进:索引节点的阶数依赖于被索引字段的最大长度,在建立索引时,先计算关键字的最大长度,所有关键字按照计算的最大长度分配空间,然后根据这个最大长度调整B+树的阶数,使索引节点的长度恰好不超过一页,也就是说对于不同的索引,其B+树的阶数可能是不同的,索引节点的长度也可能是不同的,这样的好处是:提高空间利用率,提升索引节点阶数,降低B+树高度,减少IO次数,减小索引的占用空间。新的索引节点结构如下图:

 

新的索引节点结构

 

    不仅索引节点要修改,关键字结构也需要重新设计。之前的关键字结构只是所有被索引字段值的复合,这种关键字结构可能在删除时出现性能问题,举个例子:在删除符合条件的行时,数据库可能先通过全表扫描找到满足条件的行的地址,然后根据数据行和它的地址在索引中查找指向该行的链接节点并更新,而对于关键字分布非常密集的索引来说,这个查找过程的时间代价可能退化为O(n),效率很低。

 

    上述的效率问题是因为无法根据数据行和该行的地址快速找到索引中指向该行的链接结点,必须遍历链接结点的链表。经过思考,发现这个问题可以通过修改关键字结构来解决,在建立索引时,将数据行地址作为被索引字段后缀组成关键字,这样能保证索引中不可能出现相同关键字,取消链接结点。一般情况下地址后缀是隐藏的,不参与关键字的比较运算,只有更新索引时地址后缀才参与关键字的比较,这样就保证了更新索引的所有查找都是在二分,最坏时间代价仅为O(log(n))。

 

    我按照上述的设计重新实现了索引,测试结果符合预期,对640W行的表建立索引后,单行查找最多只要6次IO,全不命中的单行查找用时10~60ms左右,与myisam的查找速度相当。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值